From d888298afd1d6875487be215596ce4dbedaa00d4 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Sat, 21 Apr 2018 03:39:25 -0700 Subject: [PATCH 01/62] Added struct for PldHeader and related function --- bindings/py3devil1.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 bindings/py3devil1.py diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py new file mode 100644 index 0000000..b520e39 --- /dev/null +++ b/bindings/py3devil1.py @@ -0,0 +1,21 @@ +import ctypes + +class PldHeader(ctypes.Structure): + _fields_ = [ + ("numOffset", ctypes.c_int), + ("offsets", ctypes.POINTER(ctypes.c_int)) + ] + +class Devil1FN_PLD(ctypes.Structure): + _fields_ = [ + ("getheader" , ctypes.CFUNCTYPE(bool, ctypes.POINTER(PldHeader), ctypes.c_char_p)), + ("sizeofsector", ctypes.CFUNCTYPE(int, ctypes.POINTER(PldHeader), ctypes.c_int)), + ("printheader" , ctypes.CFUNCTYPE(None, ctypes.POINTER(PldHeader))) + ] + +def main(): + libc = cdll.LoadLibrary('./libdevil1pld.so') + if (lib): + print("OK") + with open("pl01.pld", "rb") as f: + data = f.read() From 3f76eddbcec596be8f08d2981d9a20f76e5c1d89 Mon Sep 17 00:00:00 2001 From: surkeh Date: Sat, 21 Apr 2018 15:44:09 -0700 Subject: [PATCH 02/62] Makefile creates .so (internall a .dll on windows?) --- .gitignore | 3 ++- Makefile | 23 ++++++++++++++++------- bindings/py3devil1.py | 15 ++++++++++----- 3 files changed, 28 insertions(+), 13 deletions(-) mode change 100644 => 100755 bindings/py3devil1.py diff --git a/.gitignore b/.gitignore index 35a3473..e76c721 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,10 @@ # Files from compilation and tests *.o +*.so +*.gch *.exe *.stackdump *.log -devil1test demo-extractpld demo-extracttexture demo-extractmesh diff --git a/Makefile b/Makefile index 7cc9e14..9b199fb 100644 --- a/Makefile +++ b/Makefile @@ -1,21 +1,30 @@ +CC=gcc +CFLAGS=-I"include" -Wall -fPIC #-g +LDFLAGS=-shared +TARGET=lib3ddevil1.so PEX=demo-extractpld TEX=demo-extracttexture MEX=demo-extractmesh +OBJ=devil1pld.o devil1tex.o devil1geo.o -CC=gcc -CFLAGS= -I"include" -Wall +all: $(TARGET) demos + +$(TARGET): $(OBJ) + $(LINK.cc) $(LDFLAGS) $^ -o $@ -all: pld texture mesh -pld: devil1pld.o devil1tex.o devil1geo.o +demos: pld texture mesh + +pld: $(OBJ) $(CC) $^ demo/extractpld.c $(CFLAGS) -o $(PEX) -texture: devil1pld.o devil1tex.o devil1geo.o +texture: $(OBJ) $(CC) $^ demo/extracttexture.c $(CFLAGS) -o $(TEX) -mesh: devil1pld.o devil1tex.o devil1geo.o +mesh: $(OBJ) $(CC) $^ demo/extractmesh.c $(CFLAGS) -o $(MEX) + devil1pld.o: src/devil1pld.c $(CC) -c $^ $(CFLAGS) @@ -26,4 +35,4 @@ devil1geo.o: src/devil1geo.c $(CC) -c $^ $(CFLAGS) clean: - rm *.o $(EX) $(PEX) $(TEX) $(MEX) + rm *.o $(TARGET) $(PEX) $(TEX) $(MEX) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py old mode 100644 new mode 100755 index b520e39..61e75b3 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -1,3 +1,4 @@ +#!/usr/bin/python3 import ctypes class PldHeader(ctypes.Structure): @@ -14,8 +15,12 @@ class Devil1FN_PLD(ctypes.Structure): ] def main(): - libc = cdll.LoadLibrary('./libdevil1pld.so') - if (lib): - print("OK") - with open("pl01.pld", "rb") as f: - data = f.read() + sharedlib='./lib3ddevil1.so' + libc = cdll.LoadLibrary(sharedlib) + if (not lib): + print("Couldn't load %s" % sharedlib) + return 1 + + print("OK") + with open("pl01.pld", "rb") as f: + data = f.read() From 71f6517a94171f4378389eb2794f3e948a4133bd Mon Sep 17 00:00:00 2001 From: _ <_> Date: Sun, 22 Apr 2018 03:39:08 -0700 Subject: [PATCH 03/62] Python can read a pld header --- bindings/py3devil1.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py index 61e75b3..7480719 100755 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -7,7 +7,7 @@ class PldHeader(ctypes.Structure): ("offsets", ctypes.POINTER(ctypes.c_int)) ] -class Devil1FN_PLD(ctypes.Structure): +class Devil1PLD_FN(ctypes.Structure): _fields_ = [ ("getheader" , ctypes.CFUNCTYPE(bool, ctypes.POINTER(PldHeader), ctypes.c_char_p)), ("sizeofsector", ctypes.CFUNCTYPE(int, ctypes.POINTER(PldHeader), ctypes.c_int)), @@ -16,11 +16,21 @@ class Devil1FN_PLD(ctypes.Structure): def main(): sharedlib='./lib3ddevil1.so' - libc = cdll.LoadLibrary(sharedlib) - if (not lib): + libc = ctypes.cdll.LoadLibrary(sharedlib) + if (not libc): print("Couldn't load %s" % sharedlib) return 1 - + print("OK") + fn = Devil1PLD_FN.in_dll(libc, "DEVIL1PLD") + pldh = PldHeader() with open("pl01.pld", "rb") as f: data = f.read() + p = PldHeader() + fn.getheader(ctypes.byref(pldh), data) + fn.printheader(ctypes.byref(pldh)) + +#---------------------------------------+ + +main() + From d71a89b84087d2d040e5db8cd66adff98fbc1ef5 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Sun, 22 Apr 2018 06:02:32 -0700 Subject: [PATCH 04/62] Added python interface for texture functions --- bindings/py3devil1.py | 112 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 101 insertions(+), 11 deletions(-) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py index 7480719..dba57ee 100755 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -1,34 +1,124 @@ #!/usr/bin/python3 import ctypes +#--------------------------------------+ +# Devil 1: PLD +#--------------------------------------+ + class PldHeader(ctypes.Structure): _fields_ = [ ("numOffset", ctypes.c_int), - ("offsets", ctypes.POINTER(ctypes.c_int)) + ("offsets", ctypes.POINTER(ctypes.c_int)) ] class Devil1PLD_FN(ctypes.Structure): _fields_ = [ - ("getheader" , ctypes.CFUNCTYPE(bool, ctypes.POINTER(PldHeader), ctypes.c_char_p)), - ("sizeofsector", ctypes.CFUNCTYPE(int, ctypes.POINTER(PldHeader), ctypes.c_int)), - ("printheader" , ctypes.CFUNCTYPE(None, ctypes.POINTER(PldHeader))) + ("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 +#--------------------------------------+ + +class TexturePack(ctypes.Structure): + _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): + _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): + _fields_ = [ + ("data", ctypes.c_ubyte) + ] + +class TextureBatch(ctypes.Structure): + _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))), + ("getbatchdesc", ctypes.CFUNCTYPE( + ctypes.c_bool, + ctypes.POINTER(TextureBatchDescriptor), + ctypes.c_uint, + ctypes.c_char_p, + ctypes.c_uint)), + ("getbatch", ctypes.CFUNCTYPE( + ctypes.c_bool, + ctypes.POINTER(TextureBatch), + ctypes.c_uint, + ctypes.c_char_p, + ctypes.c_uint)), + ("gettexture", ctypes.CFUNCTYPE( + ctypes.c_bool, + ctypes.POINTER(Texture), + ctypes.c_uint, + ctypes.c_char_p, + ctypes.c_uint)) + ] + +#--------------------------------------+ +# Devil 1: GEO +#--------------------------------------+ + +#--------------------------------------+ +# Regular Python +#--------------------------------------+ + +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)) + +def textest(devil1tex, texheader): + with open("pl01.pld_1.txp", "rb") as f: + data = f.read() + texheader = ctypes.cast(data, ctypes.POINTER(TexturePack)) + devil1tex.printheader(texheader) + def main(): sharedlib='./lib3ddevil1.so' libc = ctypes.cdll.LoadLibrary(sharedlib) if (not libc): print("Couldn't load %s" % sharedlib) return 1 - print("OK") - fn = Devil1PLD_FN.in_dll(libc, "DEVIL1PLD") + pldfn = Devil1PLD_FN.in_dll(libc, "DEVIL1PLD") pldh = PldHeader() - with open("pl01.pld", "rb") as f: - data = f.read() - p = PldHeader() - fn.getheader(ctypes.byref(pldh), data) - fn.printheader(ctypes.byref(pldh)) + pldtest(pldfn, pldh) + + texfn = Devil1TEX_FN.in_dll(libc, "DEVIL1TEX") + texh = TexturePack() + textest(texfn, texh) #---------------------------------------+ From c1bb8c457fc890493f493b2b0ad004d717dd983c Mon Sep 17 00:00:00 2001 From: _ <_> Date: Sun, 22 Apr 2018 06:48:19 -0700 Subject: [PATCH 05/62] Added interface for geometry functions --- bindings/py3devil1.py | 168 +++++++++++++++++++++++++++++++++++------- 1 file changed, 143 insertions(+), 25 deletions(-) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py index dba57ee..2e2aa92 100755 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -89,38 +89,156 @@ class Devil1TEX_FN(ctypes.Structure): # Devil 1: GEO #--------------------------------------+ +class Header(ctypes.Structure): + _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): + _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): + _fields_ = [ + ("x", ctypes.c_float), + ("y", ctypes.c_float), + ("z", ctypes.c_float) + ] + +class UVs(ctypes.Structure): + _fields_ = [ + ("u", ctypes.c_short), + ("v", ctypes.c_short) + ] + +class BoneIndexes(ctypes.Structure): + _fields_ = [ + ("indexes", ctypes.c_ubyte * 4), + ] + +class BoneWeights(ctypes.Structure): + _fields_ = [ + ("weights", ctypes.c_short) + ] + + +class BatchData(ctypes.Structure): + _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): + _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): + _fields_ = [ + ("bd", ctypes.POINTER(BatchData)), + ("vd", VertexData) + ] + +class Mesh(ctypes.Structure): + _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))), + ("getmeshheader", ctypes.CFUNCTYPE( + ctypes.c_bool, + 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)) + ] + #--------------------------------------+ # 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)) -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)) + def textest(devil1tex, texheader): + with open("pl01.pld_1.txp", "rb") as f: + data = f.read() + texheader = ctypes.cast(data, ctypes.POINTER(TexturePack)) + devil1tex.printheader(texheader) -def textest(devil1tex, texheader): - with open("pl01.pld_1.txp", "rb") as f: - data = f.read() - texheader = ctypes.cast(data, ctypes.POINTER(TexturePack)) - devil1tex.printheader(texheader) + def geotest(devil1geo, geoheader): + with open("pl00.pld_0", "rb") as f: + data = f.read() + geoheader = ctypes.cast(data, ctypes.POINTER(Header)) + devil1geo.printheader(geoheader) -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) + def main(): + sharedlib='./lib3ddevil1.so' + libc = ctypes.cdll.LoadLibrary(sharedlib) + if (not libc): + print("Couldn't load %s" % sharedlib) + return 1 + print("OK") - texfn = Devil1TEX_FN.in_dll(libc, "DEVIL1TEX") - texh = TexturePack() - textest(texfn, texh) + 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) #---------------------------------------+ - -main() + main() From e111ff2e077572ac0bb39baf6a0c2f137d5ff3ee Mon Sep 17 00:00:00 2001 From: surkeh Date: Sun, 22 Apr 2018 14:59:30 -0700 Subject: [PATCH 06/62] Add __init__.py to bindings --- .gitignore | 1 + bindings/__init__.py | 0 2 files changed, 1 insertion(+) create mode 100644 bindings/__init__.py diff --git a/.gitignore b/.gitignore index e76c721..36e8bad 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ *.exe *.stackdump *.log +__pycache__ demo-extractpld demo-extracttexture demo-extractmesh diff --git a/bindings/__init__.py b/bindings/__init__.py new file mode 100644 index 0000000..e69de29 From 6d0b82682e1e0728cb3171c61abf68c4400833dd Mon Sep 17 00:00:00 2001 From: _ <_> Date: Mon, 23 Apr 2018 17:15:56 -0700 Subject: [PATCH 07/62] Added getheader() functions for tex and geo component --- include/devil1geo.h | 7 +++++-- include/devil1tex.h | 3 +++ src/devil1geo.c | 10 ++++++++++ src/devil1tex.c | 13 ++++++++++++- 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/include/devil1geo.h b/include/devil1geo.h index 7b6b3d2..6d08f1e 100644 --- a/include/devil1geo.h +++ b/include/devil1geo.h @@ -85,6 +85,9 @@ typedef struct { // input: pointer to struct void (* const printcoordinate)(struct Coordinate*, unsigned int); +// input: pointer to struct, file data + bool (* const getheader) (struct Header*, const char*); + // input: pointer of pointer to struct, order, file data // ** = 'pass by reference' of a pointer to struct bool (* const getmeshheader) (struct MeshHeader**, @@ -96,11 +99,11 @@ typedef struct { unsigned int offset, const char * const); -// input: pointer to struct, order, file data +// input: pointer to struct, order, file data, file size bool (* const getmesh) (struct Mesh*, unsigned int i, const char*, - unsigned int filesize); + unsigned int); } fn_devil1geo; extern fn_devil1geo const DEVIL1GEO; diff --git a/include/devil1tex.h b/include/devil1tex.h index 9013b2b..b002a0a 100644 --- a/include/devil1tex.h +++ b/include/devil1tex.h @@ -45,6 +45,9 @@ typedef struct { // input: pointer to struct void (* const printbatchdesc)(struct TextureBatchDescriptor*); +// input: pointer to struct, file data + bool (* const getheader) (struct TexturePack*, const char*); + // input: pointer of pointer to struct, order, file data, file size // ** = 'pass by reference' of a pointer to struct bool (* const getbatchdesc) (struct TextureBatchDescriptor**, diff --git a/src/devil1geo.c b/src/devil1geo.c index b329072..d62e13b 100644 --- a/src/devil1geo.c +++ b/src/devil1geo.c @@ -9,6 +9,7 @@ static void printmeshbatch(struct Batch*); static void printcoordinate(struct Coordinate*, unsigned int); +static bool getgheader(struct Header*, const char*); static bool getmeshheader(struct MeshHeader**, unsigned int i, const char * const); @@ -20,6 +21,7 @@ fn_devil1geo const DEVIL1GEO = {printgheader, printmeshheader, printmeshbatch, printcoordinate, + getgheader, getmeshheader, getmeshbatch, getmesh}; @@ -74,6 +76,14 @@ static void printcoordinate(struct Coordinate *p, unsigned int count) { } } +static bool getgheader(struct Header* h, const char* filedata) { + if (filedata == NULL) { + return false; + } + h = (struct Header*)filedata; + return true; +} + static bool getmeshheader(struct MeshHeader **hs, unsigned int i, const char * const filedata) { diff --git a/src/devil1tex.c b/src/devil1tex.c index 5b4d8dd..1bbf2e9 100644 --- a/src/devil1tex.c +++ b/src/devil1tex.c @@ -8,8 +8,10 @@ static void printtph(struct TexturePack*); // Print Texture Batch Descriptor. static void printtbd(struct TextureBatchDescriptor*); -// Get Texture Batch Descriptor. +// Get Texture Pack Header +static bool getpackheader(struct TexturePack*, const char*); +// Get Texture Batch Descriptor. static bool gettexdescriptor(struct TextureBatchDescriptor**, unsigned int, const char *, @@ -30,6 +32,7 @@ static bool unpacktexbatch(struct Texture*, fn_devil1tex const DEVIL1TEX = {printtph, printtbd, + getpackheader, gettexdescriptor, gettexbatch, unpacktexbatch}; @@ -55,6 +58,14 @@ static void printtbd(struct TextureBatchDescriptor *bd) { } } +static bool getpackheader(struct TexturePack* p, const char *filedata) { + if (filedata == NULL) { + return false; + } + p = (struct TexturePack*)filedata; + return true; +} + static bool gettexdescriptor(struct TextureBatchDescriptor **descriptor, unsigned int i, const char *filedata, From 046e1f8617ba27b0cedb3de78e9260888f22ab4a Mon Sep 17 00:00:00 2001 From: _ <_> Date: Mon, 23 Apr 2018 17:28:39 -0700 Subject: [PATCH 08/62] Replaced old casts with function calls --- demo/extractmesh.c | 4 ++-- demo/extracttexture.c | 3 +-- src/devil1geo.c | 6 +++--- src/devil1tex.c | 7 +++---- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/demo/extractmesh.c b/demo/extractmesh.c index 71dbe23..ba49f9b 100644 --- a/demo/extractmesh.c +++ b/demo/extractmesh.c @@ -59,10 +59,10 @@ void writemesh(const struct MeshHeader *mh, void extractmeshes(const char *filedata, const char *filename, unsigned int filesize) { - if (filedata == NULL || filesize <= 0) { + struct Header *h = NULL; + if (!(DEVIL1GEO.getheader(h, filedata))|| filesize <= 0) { return; } - struct Header *h = (struct Header*)filedata; struct MeshHeader *mh = NULL; struct Mesh m; m.b = NULL; diff --git a/demo/extracttexture.c b/demo/extracttexture.c index f686ff7..839ad84 100644 --- a/demo/extracttexture.c +++ b/demo/extracttexture.c @@ -8,10 +8,9 @@ void extracttextures(const char *filedata, struct Texture *t = NULL; struct TextureBatchDescriptor *d = NULL; char * fmt = NULL; - if (filedata == NULL || filesize == 0) { + if (!(DEVIL1TEX.getheader(p, filedata)) || filesize == 0) { return; } - p = (struct TexturePack*)filedata; fmt = (char*)malloc(strlen(filename) + 3 + 4); unsigned int i; unsigned int j; diff --git a/src/devil1geo.c b/src/devil1geo.c index d62e13b..70f5bd8 100644 --- a/src/devil1geo.c +++ b/src/devil1geo.c @@ -87,11 +87,11 @@ static bool getgheader(struct Header* h, const char* filedata) { static bool getmeshheader(struct MeshHeader **hs, unsigned int i, const char * const filedata) { - bool done = false; - if (hs == NULL || filedata == NULL) { + bool done = false; + struct Header *h = NULL; + if (hs == NULL || !(getgheader(h, filedata))) { return done; } - struct Header *h = (struct Header*)filedata; if (h -> numMesh < i) { return done; } diff --git a/src/devil1tex.c b/src/devil1tex.c index 1bbf2e9..92bc717 100644 --- a/src/devil1tex.c +++ b/src/devil1tex.c @@ -9,7 +9,7 @@ static void printtph(struct TexturePack*); static void printtbd(struct TextureBatchDescriptor*); // Get Texture Pack Header -static bool getpackheader(struct TexturePack*, const char*); +static inline bool getpackheader(struct TexturePack*, const char*); // Get Texture Batch Descriptor. static bool gettexdescriptor(struct TextureBatchDescriptor**, @@ -58,7 +58,7 @@ static void printtbd(struct TextureBatchDescriptor *bd) { } } -static bool getpackheader(struct TexturePack* p, const char *filedata) { +inline static bool getpackheader(struct TexturePack* p, const char *filedata) { if (filedata == NULL) { return false; } @@ -86,10 +86,9 @@ static bool gettexbatch(struct TextureBatch **batch, const char *filedata, unsigned int filesize) { struct TexturePack *p = NULL; - if (filedata == NULL) { // no data to get batch from. + if (!(getpackheader(p, filedata))) { return false; } - p = (struct TexturePack*)filedata; if (i > p -> batchNumber) { // no such batch in texture pack return false; } From 9a14430a8839432cbef8dfb575c92ae29686feb1 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Mon, 23 Apr 2018 17:43:04 -0700 Subject: [PATCH 09/62] Fixed segmentation fault by clarifying pointer of pointer --- demo/extractmesh.c | 2 +- demo/extracttexture.c | 2 +- include/devil1geo.h | 2 +- include/devil1tex.h | 2 +- src/devil1geo.c | 8 ++++---- src/devil1tex.c | 8 ++++---- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/demo/extractmesh.c b/demo/extractmesh.c index ba49f9b..d15dde7 100644 --- a/demo/extractmesh.c +++ b/demo/extractmesh.c @@ -60,7 +60,7 @@ void extractmeshes(const char *filedata, const char *filename, unsigned int filesize) { struct Header *h = NULL; - if (!(DEVIL1GEO.getheader(h, filedata))|| filesize <= 0) { + if (!(DEVIL1GEO.getheader(&h, filedata))|| filesize <= 0) { return; } struct MeshHeader *mh = NULL; diff --git a/demo/extracttexture.c b/demo/extracttexture.c index 839ad84..8a187c3 100644 --- a/demo/extracttexture.c +++ b/demo/extracttexture.c @@ -8,7 +8,7 @@ void extracttextures(const char *filedata, struct Texture *t = NULL; struct TextureBatchDescriptor *d = NULL; char * fmt = NULL; - if (!(DEVIL1TEX.getheader(p, filedata)) || filesize == 0) { + if (!(DEVIL1TEX.getheader(&p, filedata)) || filesize == 0) { return; } fmt = (char*)malloc(strlen(filename) + 3 + 4); diff --git a/include/devil1geo.h b/include/devil1geo.h index 6d08f1e..7293041 100644 --- a/include/devil1geo.h +++ b/include/devil1geo.h @@ -86,7 +86,7 @@ typedef struct { void (* const printcoordinate)(struct Coordinate*, unsigned int); // input: pointer to struct, file data - bool (* const getheader) (struct Header*, const char*); + bool (* const getheader) (struct Header**, const char*); // input: pointer of pointer to struct, order, file data // ** = 'pass by reference' of a pointer to struct diff --git a/include/devil1tex.h b/include/devil1tex.h index b002a0a..f45be35 100644 --- a/include/devil1tex.h +++ b/include/devil1tex.h @@ -46,7 +46,7 @@ typedef struct { void (* const printbatchdesc)(struct TextureBatchDescriptor*); // input: pointer to struct, file data - bool (* const getheader) (struct TexturePack*, const char*); + bool (* const getheader) (struct TexturePack**, const char*); // input: pointer of pointer to struct, order, file data, file size // ** = 'pass by reference' of a pointer to struct diff --git a/src/devil1geo.c b/src/devil1geo.c index 70f5bd8..72357af 100644 --- a/src/devil1geo.c +++ b/src/devil1geo.c @@ -9,7 +9,7 @@ static void printmeshbatch(struct Batch*); static void printcoordinate(struct Coordinate*, unsigned int); -static bool getgheader(struct Header*, const char*); +static bool getgheader(struct Header**, const char*); static bool getmeshheader(struct MeshHeader**, unsigned int i, const char * const); @@ -76,11 +76,11 @@ static void printcoordinate(struct Coordinate *p, unsigned int count) { } } -static bool getgheader(struct Header* h, const char* filedata) { +static bool getgheader(struct Header** h, const char* filedata) { if (filedata == NULL) { return false; } - h = (struct Header*)filedata; + (*h) = (struct Header*)filedata; return true; } @@ -89,7 +89,7 @@ static bool getmeshheader(struct MeshHeader **hs, const char * const filedata) { bool done = false; struct Header *h = NULL; - if (hs == NULL || !(getgheader(h, filedata))) { + if (hs == NULL || !(getgheader(&h, filedata))) { return done; } if (h -> numMesh < i) { diff --git a/src/devil1tex.c b/src/devil1tex.c index 92bc717..f284cd8 100644 --- a/src/devil1tex.c +++ b/src/devil1tex.c @@ -9,7 +9,7 @@ static void printtph(struct TexturePack*); static void printtbd(struct TextureBatchDescriptor*); // Get Texture Pack Header -static inline bool getpackheader(struct TexturePack*, const char*); +static inline bool getpackheader(struct TexturePack**, const char*); // Get Texture Batch Descriptor. static bool gettexdescriptor(struct TextureBatchDescriptor**, @@ -58,11 +58,11 @@ static void printtbd(struct TextureBatchDescriptor *bd) { } } -inline static bool getpackheader(struct TexturePack* p, const char *filedata) { +inline static bool getpackheader(struct TexturePack** p, const char *filedata) { if (filedata == NULL) { return false; } - p = (struct TexturePack*)filedata; + (*p) = (struct TexturePack*)filedata; return true; } @@ -86,7 +86,7 @@ static bool gettexbatch(struct TextureBatch **batch, const char *filedata, unsigned int filesize) { struct TexturePack *p = NULL; - if (!(getpackheader(p, filedata))) { + if (!(getpackheader(&p, filedata))) { return false; } if (i > p -> batchNumber) { // no such batch in texture pack From 438ba04efb87ad19a850582462cfd359a816e61d Mon Sep 17 00:00:00 2001 From: _ <_> Date: Mon, 23 Apr 2018 17:59:46 -0700 Subject: [PATCH 10/62] Added bindings for new functions --- bindings/py3devil1.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py index 2e2aa92..ddccd4c 100755 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -65,6 +65,10 @@ class Devil1TEX_FN(ctypes.Structure): ("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(TextureBatchDescriptor), @@ -179,6 +183,10 @@ class Devil1GEO_FN(ctypes.Structure): ("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(MeshHeader), From 360d57477d4b5157f3261b0cc20f7ead52423d05 Mon Sep 17 00:00:00 2001 From: surkeh Date: Mon, 23 Apr 2018 18:57:57 -0700 Subject: [PATCH 11/62] Add *.gch to make clean recipe --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9b199fb..ee67998 100644 --- a/Makefile +++ b/Makefile @@ -35,4 +35,4 @@ devil1geo.o: src/devil1geo.c $(CC) -c $^ $(CFLAGS) clean: - rm *.o $(TARGET) $(PEX) $(TEX) $(MEX) + rm *.o *.gch $(TARGET) $(PEX) $(TEX) $(MEX) From 918e12544db75857aa6e7001620b3d080ff421de Mon Sep 17 00:00:00 2001 From: _ <_> Date: Tue, 24 Apr 2018 03:58:51 -0700 Subject: [PATCH 12/62] Fixed getmeshheader() --- bindings/py3devil1.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py index ddccd4c..fea8911 100755 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -189,7 +189,7 @@ class Devil1GEO_FN(ctypes.Structure): ctypes.c_char_p)), ("getmeshheader", ctypes.CFUNCTYPE( ctypes.c_bool, - ctypes.POINTER(MeshHeader), + ctypes.POINTER(ctypes.POINTER(MeshHeader)), ctypes.c_uint, ctypes.c_char_p)), ("getbatch", ctypes.CFUNCTYPE( @@ -224,8 +224,14 @@ if __name__ == "__main__": def geotest(devil1geo, geoheader): with open("pl00.pld_0", "rb") as f: data = f.read() - geoheader = ctypes.cast(data, ctypes.POINTER(Header)) +# geoheader = ctypes.cast(data, ctypes.POINTER(Header)) + gh = ctypes.pointer(geoheader) + devil1geo.getheader(ctypes.byref(gh), data) devil1geo.printheader(geoheader) + meshheader = MeshHeader() + mh = ctypes.pointer(meshheader) + devil1geo.getmeshheader(ctypes.byref(mh), 1, data) + devil1geo.printmeshheader(mh) def main(): sharedlib='./lib3ddevil1.so' From 16ece81bcff463612bcd6e717316037e7e5353dc Mon Sep 17 00:00:00 2001 From: _ <_> Date: Tue, 24 Apr 2018 04:08:52 -0700 Subject: [PATCH 13/62] Fixed getbatchdesc() --- bindings/py3devil1.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py index fea8911..8abc301 100755 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -67,17 +67,20 @@ class Devil1TEX_FN(ctypes.Structure): ctypes.POINTER(TextureBatchDescriptor))), ("getheader", ctypes.CFUNCTYPE( ctypes.c_bool, - ctypes.POINTER(ctypes.POINTER(TexturePack)), + ctypes.POINTER( + ctypes.POINTER(TexturePack)), ctypes.c_char_p)), ("getbatchdesc", ctypes.CFUNCTYPE( ctypes.c_bool, - ctypes.POINTER(TextureBatchDescriptor), + ctypes.POINTER( + ctypes.POINTER(TextureBatchDescriptor)), ctypes.c_uint, ctypes.c_char_p, ctypes.c_uint)), ("getbatch", ctypes.CFUNCTYPE( ctypes.c_bool, - ctypes.POINTER(TextureBatch), + ctypes.POINTER( + ctypes.POINTER(TextureBatch)), ctypes.c_uint, ctypes.c_char_p, ctypes.c_uint)), @@ -218,8 +221,14 @@ if __name__ == "__main__": def textest(devil1tex, texheader): with open("pl01.pld_1.txp", "rb") as f: data = f.read() - texheader = ctypes.cast(data, ctypes.POINTER(TexturePack)) - devil1tex.printheader(texheader) +# 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)) def geotest(devil1geo, geoheader): with open("pl00.pld_0", "rb") as f: From 7736a50e7ff71f82907945e18ecd298fd265fb2d Mon Sep 17 00:00:00 2001 From: _ <_> Date: Tue, 24 Apr 2018 04:58:21 -0700 Subject: [PATCH 14/62] Fixed typo and correctly print geoheader --- bindings/py3devil1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py index 8abc301..fea35be 100755 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -236,7 +236,7 @@ if __name__ == "__main__": # geoheader = ctypes.cast(data, ctypes.POINTER(Header)) gh = ctypes.pointer(geoheader) devil1geo.getheader(ctypes.byref(gh), data) - devil1geo.printheader(geoheader) + devil1geo.printheader(gh) meshheader = MeshHeader() mh = ctypes.pointer(meshheader) devil1geo.getmeshheader(ctypes.byref(mh), 1, data) From 85857024714643943076034e7432dbf123100296 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Tue, 24 Apr 2018 18:46:10 -0700 Subject: [PATCH 15/62] Fixed access of offset attribute in PldHeader --- bindings/py3devil1.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py index fea35be..4e67102 100755 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -6,6 +6,7 @@ import ctypes #--------------------------------------+ class PldHeader(ctypes.Structure): + _pack_ = 1 _fields_ = [ ("numOffset", ctypes.c_int), ("offsets", ctypes.POINTER(ctypes.c_int)) @@ -217,6 +218,10 @@ if __name__ == "__main__": data = f.read() devil1pld.getheader(ctypes.byref(pldheader), data) devil1pld.printheader(ctypes.byref(pldheader)) + print(pldheader) + print(pldheader.numOffset) + for i in range(0, pldheader.numOffset): + print(hex(pldheader.offsets[i])) def textest(devil1tex, texheader): with open("pl01.pld_1.txp", "rb") as f: From 790afd9960a028eb46bd9b75346639d9bbdfe005 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Tue, 24 Apr 2018 19:15:39 -0700 Subject: [PATCH 16/62] Added pack to packed structs --- bindings/py3devil1.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py index 4e67102..d20cf1c 100755 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -31,6 +31,7 @@ class Devil1PLD_FN(ctypes.Structure): #--------------------------------------+ class TexturePack(ctypes.Structure): + _pack_ = 1 _fields_ = [ ("id", ctypes.c_char * 4), # fixed length 4, reverse order ("batchNumber", ctypes.c_int), @@ -39,6 +40,7 @@ class TexturePack(ctypes.Structure): ] class TextureBatchDescriptor(ctypes.Structure): + _pack_ = 1 _fields_ = [ ("batchIdx", ctypes.c_int), ("hash", ctypes.c_int), @@ -49,11 +51,13 @@ class TextureBatchDescriptor(ctypes.Structure): ] class Texture(ctypes.Structure): + _pack_ = 1 _fields_ = [ ("data", ctypes.c_ubyte) ] class TextureBatch(ctypes.Structure): + _pack_ = 1 _fields_ = [ ("batch", ctypes.POINTER(Texture)) ] @@ -98,6 +102,7 @@ class Devil1TEX_FN(ctypes.Structure): #--------------------------------------+ class Header(ctypes.Structure): + _pack_ = 1 _fields_ = [ ("numMesh", ctypes.c_ubyte), ("unknownNumberB", ctypes.c_ubyte), @@ -108,6 +113,7 @@ class Header(ctypes.Structure): ] class MeshHeader(ctypes.Structure): + _pack_ = 1 _fields_ = [ ("numBatch", ctypes.c_short), ("numVertex", ctypes.c_short), @@ -117,6 +123,7 @@ class MeshHeader(ctypes.Structure): ] class Coordinate(ctypes.Structure): + _pack_ = 1 _fields_ = [ ("x", ctypes.c_float), ("y", ctypes.c_float), @@ -124,23 +131,27 @@ class Coordinate(ctypes.Structure): ] class UVs(ctypes.Structure): + _pack_ = 1 _fields_ = [ ("u", ctypes.c_short), ("v", ctypes.c_short) ] 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), @@ -154,6 +165,7 @@ class BatchData(ctypes.Structure): ] class VertexData(ctypes.Structure): + _pack_ = 1 _fields_ = [ ("positions", ctypes.POINTER(Coordinate)), ("normals", ctypes.POINTER(Coordinate)), @@ -163,12 +175,14 @@ class VertexData(ctypes.Structure): ] class Batch(ctypes.Structure): + _pack_ = 1 _fields_ = [ ("bd", ctypes.POINTER(BatchData)), ("vd", VertexData) ] class Mesh(ctypes.Structure): + _pack_ = 1 _fields_ = [ ("b", ctypes.POINTER(Batch)) ] @@ -220,6 +234,7 @@ if __name__ == "__main__": devil1pld.printheader(ctypes.byref(pldheader)) print(pldheader) print(pldheader.numOffset) + print(pldheader.offsets) for i in range(0, pldheader.numOffset): print(hex(pldheader.offsets[i])) From 01815bc90f80a6c3cd58a731577c24a21ea0096c Mon Sep 17 00:00:00 2001 From: _ <_> Date: Tue, 24 Apr 2018 19:25:26 -0700 Subject: [PATCH 17/62] Added demonstration of design --- bindings/py3devil1.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py index d20cf1c..82bb2a0 100755 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -12,6 +12,12 @@ class PldHeader(ctypes.Structure): ("offsets", ctypes.POINTER(ctypes.c_int)) ] + def getoffsets(self): + pyoffsets = [] + for i in range(0, self.numOffset): + pyoffsets.append(self.offsets[i]) + return pyoffsets + class Devil1PLD_FN(ctypes.Structure): _fields_ = [ ("getheader" , ctypes.CFUNCTYPE( @@ -232,11 +238,8 @@ if __name__ == "__main__": data = f.read() devil1pld.getheader(ctypes.byref(pldheader), data) devil1pld.printheader(ctypes.byref(pldheader)) - print(pldheader) - print(pldheader.numOffset) - print(pldheader.offsets) - for i in range(0, pldheader.numOffset): - print(hex(pldheader.offsets[i])) + for offset in pldheader.getoffsets(): + print(hex(offset)) def textest(devil1tex, texheader): with open("pl01.pld_1.txp", "rb") as f: From a349c8da52436b4817dafe0a8a4146967faac467 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Tue, 24 Apr 2018 21:19:44 -0700 Subject: [PATCH 18/62] Added pythonic PLDHeader object --- bindings/py3devil1.py | 51 +++++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py index 82bb2a0..a3ed6d2 100755 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -1,8 +1,8 @@ #!/usr/bin/python3 -import ctypes +import ctypes, sys #--------------------------------------+ -# Devil 1: PLD +# Devil 1: PLD Base #--------------------------------------+ class PldHeader(ctypes.Structure): @@ -12,12 +12,6 @@ class PldHeader(ctypes.Structure): ("offsets", ctypes.POINTER(ctypes.c_int)) ] - def getoffsets(self): - pyoffsets = [] - for i in range(0, self.numOffset): - pyoffsets.append(self.offsets[i]) - return pyoffsets - class Devil1PLD_FN(ctypes.Structure): _fields_ = [ ("getheader" , ctypes.CFUNCTYPE( @@ -33,7 +27,7 @@ class Devil1PLD_FN(ctypes.Structure): ] #--------------------------------------+ -# Devil 1: TEX +# Devil 1: TEX Base #--------------------------------------+ class TexturePack(ctypes.Structure): @@ -104,7 +98,7 @@ class Devil1TEX_FN(ctypes.Structure): ] #--------------------------------------+ -# Devil 1: GEO +# Devil 1: GEO Base #--------------------------------------+ class Header(ctypes.Structure): @@ -229,6 +223,35 @@ class Devil1GEO_FN(ctypes.Structure): ctypes.c_uint)) ] +#--------------------------------------+ +# Python Objs +#--------------------------------------+ + +sharedlib = './lib3ddevil1.so' +libc = ctypes.cdll.LoadLibrary(sharedlib) +if not libc: + print("Couldn't load %s" % sharedlib) + sys.exit() + +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): + h = PldHeader() + devil1pld.getheader(ctypes.byref(h), filedata) + self.offsets = [] + for i in range(0, h.numOffset): + self.offsets.append(h.offsets[i]) + + def __str__(self): + output = "numOffset: %s" % str(len(self.offsets)) + for offset in self.offsets: + output += "\n\t" + str(hex(offset)) + return output + #--------------------------------------+ # Regular Python #--------------------------------------+ @@ -285,6 +308,12 @@ if __name__ == "__main__": geoh = Header() geotest(geofn, geoh) + def mainx(): + with open("pl01.pld", "rb") as f: + data = f.read() + pld = PLDHeader(data) + print(pld) #---------------------------------------+ - main() + # main() + mainx() From e06d7dcd8fd96fcab97bd9781385e433b3a97221 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Tue, 24 Apr 2018 21:51:11 -0700 Subject: [PATCH 19/62] Adjusted constructor to allow default 'blank' pld's --- bindings/py3devil1.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py index a3ed6d2..0e54412 100755 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -239,12 +239,12 @@ devil1tex = Devil1TEX_FN.in_dll(libc, "DEVIL1TEX") devil1geo = Devil1GEO_FN.in_dll(libc, "DEVIL1GEO") class PLDHeader: - def __init__(self, filedata): - h = PldHeader() - devil1pld.getheader(ctypes.byref(h), filedata) + def __init__(self, filedata = None): self.offsets = [] - for i in range(0, h.numOffset): - self.offsets.append(h.offsets[i]) + if filedata: + h = PldHeader() + devil1pld.getheader(ctypes.byref(h), filedata) + self.offsets = h.offsets[:h.numOffset] def __str__(self): output = "numOffset: %s" % str(len(self.offsets)) @@ -313,6 +313,8 @@ if __name__ == "__main__": data = f.read() pld = PLDHeader(data) print(pld) + pld2 = PLDHeader() + print(pld2) #---------------------------------------+ # main() mainx() From be691baffb2b8ed72d208f2d5e6a56d5aaa03b25 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Fri, 27 Apr 2018 04:42:18 -0700 Subject: [PATCH 20/62] Added python interface of texture component --- bindings/py3devil1.py | 97 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 86 insertions(+), 11 deletions(-) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py index 0e54412..24b9ada 100755 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -240,17 +240,87 @@ devil1geo = Devil1GEO_FN.in_dll(libc, "DEVIL1GEO") class PLDHeader: def __init__(self, filedata = None): - self.offsets = [] +# self.offsets = [] +# if filedata: +# h = PldHeader() +# devil1pld.getheader(ctypes.byref(h), filedata) +# self.offsets = h.offsets[:h.numOffset] +# self.offsets.append(len(filedata)) + # Store C Struct in order to call C functions + self.cstruct = PldHeader() if filedata: - h = PldHeader() - devil1pld.getheader(ctypes.byref(h), filedata) - self.offsets = h.offsets[:h.numOffset] + devil1pld.getheader(ctypes.byref(self.cstruct), filedata) + self.eof = len(filedata) - def __str__(self): - output = "numOffset: %s" % str(len(self.offsets)) - for offset in self.offsets: - output += "\n\t" + str(hex(offset)) - return output + # def __str__(self): + # output = "numOffset: %s" % str(len(self.offsets)) + # for offset in self.offsets: + # output += "\n\t" + str(hex(offset)) + # return output + + 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 = TexturePack() + self.th = ctypes.pointer(self.cstruct) + devil1tex.getheader(ctypes.byref(self.th), filedata) + devil1tex.printheader(self.th) + return + + def show(self): + devil1tex.printheader(ctypes.byref(self.cstruct)) + devil1tex.printheader(self.th) + + def getbatchno(self): + return self.cstruct.batchNumber + + def getfirstbatchoffset(self): + return self.cstruct.firstBatchOffset + +class TEXtureBatchDescriptor: + def __init__(self, i, filedata): + self.cstruct = TextureBatchDescriptor() + ptrofptr = ctypes.byref(ctypes.byref(self.cstruct)) + if filedata(): + devil1tex.getbatchdesc(ptrofptr, i, filedata, len(filedata)) + return + + def show(self): + ptr = ctypes.byref(self.cstruct) + devil1tex.printbatchdesc(ptr) + + def getbatchidx(self): + return self.cstruct.batchIdx + + def gethash(self): + return self.cstruct.hash + + def gettexno(self): + return self.cstruct.texNumber + + def gettexturesize(self): + return self.cstruct.textureSize + +class TEXtures: + def __init__(self, i, batchdescriptor, filedata): + self.cstruct = Texture()[batchdescriptor.gettexno()] + if filedata: + devil1tex.gettextures(self.cstruct, i, filedata, len(filedata)) + return #--------------------------------------+ # Regular Python @@ -312,9 +382,14 @@ if __name__ == "__main__": with open("pl01.pld", "rb") as f: data = f.read() pld = PLDHeader(data) - print(pld) + pld.show() pld2 = PLDHeader() - print(pld2) + pld2.show() + + with open("pl01.pld_1.txp", "rb") as f: + data = f.read() + txp = TEXturePack(data) + txp.show() #---------------------------------------+ # main() mainx() From 62841adcb96f212b1946322f6ea8640f5ef3c7f2 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Fri, 27 Apr 2018 04:44:55 -0700 Subject: [PATCH 21/62] Fixed TEXturePack struct --- bindings/py3devil1.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py index 24b9ada..20c5b4d 100755 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -275,21 +275,18 @@ class PLDHeader: class TEXturePack: def __init__(self, filedata): - self.cstruct = TexturePack() - self.th = ctypes.pointer(self.cstruct) - devil1tex.getheader(ctypes.byref(self.th), filedata) - devil1tex.printheader(self.th) + self.cstruct = ctypes.pointer(TexturePack()) + devil1tex.getheader(ctypes.byref(self.cstruct), filedata) return def show(self): - devil1tex.printheader(ctypes.byref(self.cstruct)) - devil1tex.printheader(self.th) + devil1tex.printheader(self.cstruct) def getbatchno(self): - return self.cstruct.batchNumber + return self.cstruct.contents.batchNumber def getfirstbatchoffset(self): - return self.cstruct.firstBatchOffset + return self.cstruct.contents.firstBatchOffset class TEXtureBatchDescriptor: def __init__(self, i, filedata): @@ -390,6 +387,8 @@ if __name__ == "__main__": data = f.read() txp = TEXturePack(data) txp.show() + print(txp.getbatchno()) + print(txp.getfirstbatchoffset()) #---------------------------------------+ # main() mainx() From b30359aabc1a25528cf39f10f666343e2dd106fc Mon Sep 17 00:00:00 2001 From: _ <_> Date: Fri, 27 Apr 2018 04:57:35 -0700 Subject: [PATCH 22/62] Fixed TEXtureBatchDescriptor --- bindings/py3devil1.py | 53 ++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py index 20c5b4d..bf879af 100755 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -240,24 +240,12 @@ devil1geo = Devil1GEO_FN.in_dll(libc, "DEVIL1GEO") class PLDHeader: def __init__(self, filedata = None): -# self.offsets = [] -# if filedata: -# h = PldHeader() -# devil1pld.getheader(ctypes.byref(h), filedata) -# self.offsets = h.offsets[:h.numOffset] -# self.offsets.append(len(filedata)) # 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 __str__(self): - # output = "numOffset: %s" % str(len(self.offsets)) - # for offset in self.offsets: - # output += "\n\t" + str(hex(offset)) - # return output - def show(self): devil1pld.printheader(ctypes.byref(self.cstruct)) return @@ -290,27 +278,26 @@ class TEXturePack: class TEXtureBatchDescriptor: def __init__(self, i, filedata): - self.cstruct = TextureBatchDescriptor() - ptrofptr = ctypes.byref(ctypes.byref(self.cstruct)) - if filedata(): + self.cstruct = ctypes.pointer(TextureBatchDescriptor()) + ptrofptr = ctypes.byref(self.cstruct) + if filedata: devil1tex.getbatchdesc(ptrofptr, i, filedata, len(filedata)) return - def show(self): - ptr = ctypes.byref(self.cstruct) - devil1tex.printbatchdesc(ptr) + def show(self): + devil1tex.printbatchdesc(self.cstruct) - def getbatchidx(self): - return self.cstruct.batchIdx + def getbatchidx(self): + return self.cstruct.contents.batchIdx - def gethash(self): - return self.cstruct.hash + def gethash(self): + return self.cstruct.contents.hash - def gettexno(self): - return self.cstruct.texNumber + def gettexno(self): + return self.cstruct.contents.texNumber - def gettexturesize(self): - return self.cstruct.textureSize + def gettexturesize(self): + return self.cstruct.contents.textureSize class TEXtures: def __init__(self, i, batchdescriptor, filedata): @@ -328,10 +315,11 @@ if __name__ == "__main__": data = f.read() devil1pld.getheader(ctypes.byref(pldheader), data) devil1pld.printheader(ctypes.byref(pldheader)) - for offset in pldheader.getoffsets(): - print(hex(offset)) + # 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)) @@ -342,8 +330,11 @@ if __name__ == "__main__": 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)) @@ -389,7 +380,11 @@ if __name__ == "__main__": txp.show() print(txp.getbatchno()) print(txp.getfirstbatchoffset()) + tbd = TEXtureBatchDescriptor(1, data) + tbd.show() + print(tbd.gettexturesize()) + #---------------------------------------+ - # main() + main() mainx() From 626fc66d6462fe856a39fac9ea6ae9a84e78e482 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Fri, 27 Apr 2018 05:25:26 -0700 Subject: [PATCH 23/62] Added notice about questionably working Textures --- bindings/py3devil1.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py index bf879af..9b958cf 100755 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -89,7 +89,7 @@ class Devil1TEX_FN(ctypes.Structure): ctypes.c_uint, ctypes.c_char_p, ctypes.c_uint)), - ("gettexture", ctypes.CFUNCTYPE( + ("gettextures", ctypes.CFUNCTYPE( ctypes.c_bool, ctypes.POINTER(Texture), ctypes.c_uint, @@ -299,9 +299,12 @@ class TEXtureBatchDescriptor: def gettexturesize(self): return self.cstruct.contents.textureSize + +# Needs testing / correction - gettextures will 'return by parameter' +# a dynamic array of textures. Need to be able to access multiple Texture() class TEXtures: - def __init__(self, i, batchdescriptor, filedata): - self.cstruct = Texture()[batchdescriptor.gettexno()] + def __init__(self, i, count, filedata): + self.cstruct = ctypes.byref(Texture()) if filedata: devil1tex.gettextures(self.cstruct, i, filedata, len(filedata)) return @@ -383,6 +386,7 @@ if __name__ == "__main__": tbd = TEXtureBatchDescriptor(1, data) tbd.show() print(tbd.gettexturesize()) + tx = TEXtures(0, tbd.gettexno(), data) #---------------------------------------+ main() From accf440047793abd6e44f19071ce3778799c4ad8 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Sun, 13 May 2018 01:08:56 -0700 Subject: [PATCH 24/62] Added interface for GEOHeader --- bindings/py3devil1.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py index 9b958cf..18d1e67 100755 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -309,6 +309,18 @@ class TEXtures: devil1tex.gettextures(self.cstruct, i, filedata, len(filedata)) return +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) + pass + #--------------------------------------+ # Regular Python #--------------------------------------+ @@ -388,7 +400,12 @@ if __name__ == "__main__": print(tbd.gettexturesize()) tx = TEXtures(0, tbd.gettexno(), data) + with open("pl00.pld_0", "rb") as f: + data = f.read() + gh = GEOHeader(data) + gh.show() + #---------------------------------------+ - main() + # main() mainx() From 49a3c8f0b7965347f940979c981f6362c4dcd88e Mon Sep 17 00:00:00 2001 From: _ <_> Date: Sun, 13 May 2018 01:33:12 -0700 Subject: [PATCH 25/62] Added init and show for mesh headers --- bindings/py3devil1.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py index 18d1e67..6554ed5 100755 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -321,6 +321,18 @@ class GEOHeader: devil1geo.printheader(self.cstruct) pass +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) + #--------------------------------------+ # Regular Python #--------------------------------------+ @@ -404,6 +416,8 @@ if __name__ == "__main__": data = f.read() gh = GEOHeader(data) gh.show() + mh = MEShHeader(3, data) + mh.show() #---------------------------------------+ # main() From e4aeba9421880f6c615662c34a5bdcc375e1b5db Mon Sep 17 00:00:00 2001 From: _ <_> Date: Sun, 13 May 2018 02:44:05 -0700 Subject: [PATCH 26/62] Added init and show for Meshes --- bindings/py3devil1.py | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py index 6554ed5..4a60930 100755 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -333,6 +333,31 @@ class MEShHeader: def show(self): devil1geo.printmeshheader(self.cstruct) + def getbatchno(self): + return self.cstruct.contents.numBatch + +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") + return + + def show(self): + if self.cstruct.b: + devil1geo.printbatch(self.cstruct.b) + else: + print("nothing to show") + #--------------------------------------+ # Regular Python #--------------------------------------+ @@ -418,7 +443,8 @@ if __name__ == "__main__": gh.show() mh = MEShHeader(3, data) mh.show() - + m = MEsh(0, data) + m.show() #---------------------------------------+ # main() mainx() From 8fdc05b9c052f9dd51dbe30f9a2b8620e6e1de8c Mon Sep 17 00:00:00 2001 From: _ <_> Date: Sun, 13 May 2018 03:38:23 -0700 Subject: [PATCH 27/62] Added getpositions and printable coordinates --- bindings/py3devil1.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py index 4a60930..48f9f2e 100755 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -130,6 +130,9 @@ class Coordinate(ctypes.Structure): ("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_ = [ @@ -232,7 +235,7 @@ 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") @@ -343,13 +346,16 @@ class MEsh: 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), + 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): @@ -358,6 +364,10 @@ class MEsh: else: print("nothing to show") + def getpositions(self): + length = self.cstruct.b.contents.bd.contents.numVertex + return self.cstruct.b.contents.vd.positions[:length] + #--------------------------------------+ # Regular Python #--------------------------------------+ @@ -445,6 +455,9 @@ if __name__ == "__main__": mh.show() m = MEsh(0, data) m.show() + p = m.getpositions() + for point in p: + print(point) #---------------------------------------+ # main() mainx() From 650178f3a4ce2caa625875a5d3da73bcb35dd7d2 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Sun, 13 May 2018 03:43:50 -0700 Subject: [PATCH 28/62] Added getnormals() --- bindings/py3devil1.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py index 48f9f2e..127c2bf 100755 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -368,6 +368,10 @@ class MEsh: 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] + #--------------------------------------+ # Regular Python #--------------------------------------+ @@ -458,6 +462,9 @@ if __name__ == "__main__": p = m.getpositions() for point in p: print(point) + n = m.getnormals() + for point in n: + print(point) #---------------------------------------+ # main() mainx() From c45c8d758a599ba2febde832f88470044d67decb Mon Sep 17 00:00:00 2001 From: _ <_> Date: Sun, 13 May 2018 09:54:57 -0700 Subject: [PATCH 29/62] Added getuvs() --- bindings/py3devil1.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py index 127c2bf..9a14667 100755 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -140,6 +140,9 @@ class UVs(ctypes.Structure): ("v", ctypes.c_short) ] + def __str__(self): + return "(%s, %s)" % (str(self.u), str(self.v)) + class BoneIndexes(ctypes.Structure): _pack_ = 1 _fields_ = [ @@ -372,6 +375,10 @@ class MEsh: 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] + #--------------------------------------+ # Regular Python #--------------------------------------+ @@ -460,11 +467,17 @@ if __name__ == "__main__": 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) #---------------------------------------+ # main() mainx() From 7835a8d90d6f0188a83030a1210886e03cffcdc2 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Sun, 13 May 2018 11:28:23 -0700 Subject: [PATCH 30/62] Added get functions for bones --- bindings/py3devil1.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py index 9a14667..051df07 100755 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -379,6 +379,14 @@ class MEsh: 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 #--------------------------------------+ From a8d2cfeb4a5f76e6986f378eee6c08f0a1cbce64 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Sun, 13 May 2018 13:47:22 -0700 Subject: [PATCH 31/62] Added getbatchdata function --- bindings/py3devil1.py | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py index 051df07..65dfb27 100755 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -367,6 +367,9 @@ class MEsh: 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] @@ -474,18 +477,21 @@ if __name__ == "__main__": 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) + # 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() From cb96add3f2a564e0b6d562b49edea77061839af2 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Sun, 13 May 2018 13:52:09 -0700 Subject: [PATCH 32/62] Added getter functions for mesh header attributes --- bindings/py3devil1.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py index 65dfb27..47fd0bc 100755 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -342,6 +342,18 @@ class MEShHeader: 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() From a2d4aaae11a0739522b7e6d4f6da791995e49a1d Mon Sep 17 00:00:00 2001 From: _ <_> Date: Sun, 13 May 2018 13:53:11 -0700 Subject: [PATCH 33/62] Fixed missing colon at fn define --- bindings/py3devil1.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py index 47fd0bc..7c0ff40 100755 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -327,6 +327,7 @@ class GEOHeader: devil1geo.printheader(self.cstruct) pass + class MEShHeader: def __init__(self, i, filedata): self.cstruct = ctypes.pointer(MeshHeader()) @@ -345,7 +346,7 @@ class MEShHeader: def getnumvertex(self): return self.cstruct.contents.numVertex - def getunknown(self) + def getunknown(self): return hex(self.cstruct.contents.u) def getoffsetbatches(self): From 2f98c2a1a2140153394bfc9e9be98947fe54a169 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Sun, 13 May 2018 14:07:21 -0700 Subject: [PATCH 34/62] Added getter attributes for geo header --- bindings/py3devil1.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py index 7c0ff40..e0de918 100755 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -325,7 +325,24 @@ class GEOHeader: def show(self): devil1geo.printheader(self.cstruct) - pass + + 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: @@ -486,6 +503,13 @@ if __name__ == "__main__": 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) From b1b281cccdae99f072f76e69b6648c2ee31c07c8 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Sun, 13 May 2018 14:38:53 -0700 Subject: [PATCH 35/62] Resolve issue with getting textures. --- bindings/py3devil1.py | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py index e0de918..d63c10b 100755 --- a/bindings/py3devil1.py +++ b/bindings/py3devil1.py @@ -53,7 +53,7 @@ class TextureBatchDescriptor(ctypes.Structure): class Texture(ctypes.Structure): _pack_ = 1 _fields_ = [ - ("data", ctypes.c_ubyte) + ("data", ctypes.POINTER(ctypes.c_ubyte)) ] class TextureBatch(ctypes.Structure): @@ -305,16 +305,23 @@ class TEXtureBatchDescriptor: def gettexturesize(self): return self.cstruct.contents.textureSize - -# Needs testing / correction - gettextures will 'return by parameter' -# a dynamic array of textures. Need to be able to access multiple Texture() -class TEXtures: - def __init__(self, i, count, filedata): - self.cstruct = ctypes.byref(Texture()) +class TEXtureBatch: + def __init__(self, i, filedata): + self.cstruct = TextureBatch() if filedata: - devil1tex.gettextures(self.cstruct, i, filedata, len(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()) @@ -497,7 +504,11 @@ if __name__ == "__main__": tbd = TEXtureBatchDescriptor(1, data) tbd.show() print(tbd.gettexturesize()) - tx = TEXtures(0, tbd.gettexno(), data) + #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() From d8e1c451564c1aede9f15e31d3f68180bdbc6973 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Tue, 15 May 2018 12:42:16 -0700 Subject: [PATCH 36/62] split python file into parts --- bindings/main.py | 121 +++++++++ bindings/py3devil1.py | 546 --------------------------------------- bindings/py3devil1geo.py | 254 ++++++++++++++++++ bindings/py3devil1pld.py | 65 +++++ bindings/py3devil1tex.py | 144 +++++++++++ 5 files changed, 584 insertions(+), 546 deletions(-) create mode 100644 bindings/main.py delete mode 100755 bindings/py3devil1.py create mode 100644 bindings/py3devil1geo.py create mode 100644 bindings/py3devil1pld.py create mode 100644 bindings/py3devil1tex.py diff --git a/bindings/main.py b/bindings/main.py new file mode 100644 index 0000000..c88aa65 --- /dev/null +++ b/bindings/main.py @@ -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() diff --git a/bindings/py3devil1.py b/bindings/py3devil1.py deleted file mode 100755 index d63c10b..0000000 --- a/bindings/py3devil1.py +++ /dev/null @@ -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() - diff --git a/bindings/py3devil1geo.py b/bindings/py3devil1geo.py new file mode 100644 index 0000000..939c282 --- /dev/null +++ b/bindings/py3devil1geo.py @@ -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] diff --git a/bindings/py3devil1pld.py b/bindings/py3devil1pld.py new file mode 100644 index 0000000..ad66826 --- /dev/null +++ b/bindings/py3devil1pld.py @@ -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) + diff --git a/bindings/py3devil1tex.py b/bindings/py3devil1tex.py new file mode 100644 index 0000000..0fa32a9 --- /dev/null +++ b/bindings/py3devil1tex.py @@ -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] + From 2c44adf7a2ab98414ea2264b6d899fdc2c7be343 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Tue, 15 May 2018 15:04:53 -0700 Subject: [PATCH 37/62] Moved out repeated code to __init__ & .so loaded once only --- bindings/__init__.py | 13 +++++++++++++ bindings/main.py | 8 +++++--- bindings/py3devil1geo.py | 13 +++---------- bindings/py3devil1pld.py | 12 +++--------- bindings/py3devil1tex.py | 13 +++---------- 5 files changed, 27 insertions(+), 32 deletions(-) diff --git a/bindings/__init__.py b/bindings/__init__.py index e69de29..7262a68 100644 --- a/bindings/__init__.py +++ b/bindings/__init__.py @@ -0,0 +1,13 @@ +import sys, ctypes + +sharedlib = './lib3ddevil1.so' +libc = ctypes.cdll.LoadLibrary(sharedlib) +if not libc: + print("Couldn't load %s" % sharedlib) + sys.exit() + +# Observe how many times the .so is loaded. +print("\nlib3ddevil1 loaded.") + +# Don't need these anymore +del sys, sharedlib diff --git a/bindings/main.py b/bindings/main.py index c88aa65..290f681 100644 --- a/bindings/main.py +++ b/bindings/main.py @@ -1,6 +1,8 @@ -from py3devil1pld import * -from py3devil1tex import * -from py3devil1geo import * +from py3devil1pld import PLDHeader +from py3devil1tex import TEXturePack, TEXtureBatchDescriptor, TEXtureBatch +from py3devil1geo import GEOHeader, MEShHeader, MEsh + +#print(libc) #--------------------------------------+ # Regular Python diff --git a/bindings/py3devil1geo.py b/bindings/py3devil1geo.py index 939c282..065b11a 100644 --- a/bindings/py3devil1geo.py +++ b/bindings/py3devil1geo.py @@ -1,14 +1,6 @@ #!/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.") +import ctypes +from __init__ import libc #--------------------------------------+ # Basic Struct @@ -143,6 +135,7 @@ class Devil1GEO_FN(ctypes.Structure): ] devil1geo = Devil1GEO_FN.in_dll(libc, "DEVIL1GEO") +del libc #--------------------------------------+ # Pythonic Object diff --git a/bindings/py3devil1pld.py b/bindings/py3devil1pld.py index ad66826..c02943c 100644 --- a/bindings/py3devil1pld.py +++ b/bindings/py3devil1pld.py @@ -1,13 +1,6 @@ #!/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.") +import ctypes +from __init__ import libc #--------------------------------------+ # Basic Struct @@ -35,6 +28,7 @@ class Devil1PLD_FN(ctypes.Structure): ] devil1pld = Devil1PLD_FN.in_dll(libc, "DEVIL1PLD") +del libc #--------------------------------------+ # Pythonic Object diff --git a/bindings/py3devil1tex.py b/bindings/py3devil1tex.py index 0fa32a9..67fb1a2 100644 --- a/bindings/py3devil1tex.py +++ b/bindings/py3devil1tex.py @@ -1,14 +1,6 @@ #!/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.") +import ctypes +from __init__ import libc #--------------------------------------+ # Basic Struct @@ -82,6 +74,7 @@ class Devil1TEX_FN(ctypes.Structure): ] devil1tex = Devil1TEX_FN.in_dll(libc, "DEVIL1TEX") +del libc #--------------------------------------+ # Pythonic Object From 42e2d88734f6fb62cbca86d1a0c5ce469d043527 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Tue, 15 May 2018 17:35:24 -0700 Subject: [PATCH 38/62] Fixed importing from external directory --- bindings/py3devil1geo.py | 2 +- bindings/py3devil1pld.py | 2 +- bindings/py3devil1tex.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bindings/py3devil1geo.py b/bindings/py3devil1geo.py index 065b11a..7d5ca1b 100644 --- a/bindings/py3devil1geo.py +++ b/bindings/py3devil1geo.py @@ -1,6 +1,6 @@ #!/usr/bin/python3 import ctypes -from __init__ import libc +from .__init__ import libc #--------------------------------------+ # Basic Struct diff --git a/bindings/py3devil1pld.py b/bindings/py3devil1pld.py index c02943c..c8fd904 100644 --- a/bindings/py3devil1pld.py +++ b/bindings/py3devil1pld.py @@ -1,6 +1,6 @@ #!/usr/bin/python3 import ctypes -from __init__ import libc +from .__init__ import libc #--------------------------------------+ # Basic Struct diff --git a/bindings/py3devil1tex.py b/bindings/py3devil1tex.py index 67fb1a2..7ad661a 100644 --- a/bindings/py3devil1tex.py +++ b/bindings/py3devil1tex.py @@ -1,6 +1,6 @@ #!/usr/bin/python3 import ctypes -from __init__ import libc +from .__init__ import libc #--------------------------------------+ # Basic Struct From a5abb9d24f93800b895e9a20a7d88842a19bc2aa Mon Sep 17 00:00:00 2001 From: _ <_> Date: Wed, 16 May 2018 20:18:37 -0700 Subject: [PATCH 39/62] Added final names for pld component --- bindings/main.py | 6 +++--- bindings/py3devil1pld.py | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/bindings/main.py b/bindings/main.py index 290f681..8659ea2 100644 --- a/bindings/main.py +++ b/bindings/main.py @@ -1,4 +1,4 @@ -from py3devil1pld import PLDHeader +from py3devil1pld import PldHeader from py3devil1tex import TEXturePack, TEXtureBatchDescriptor, TEXtureBatch from py3devil1geo import GEOHeader, MEShHeader, MEsh @@ -68,9 +68,9 @@ if __name__ == "__main__": def mainx(): with open("pl01.pld", "rb") as f: data = f.read() - pld = PLDHeader(data) + pld = PldHeader(data) pld.show() - pld2 = PLDHeader() + pld2 = PldHeader() pld2.show() with open("pl01.pld_1.txp", "rb") as f: diff --git a/bindings/py3devil1pld.py b/bindings/py3devil1pld.py index c8fd904..8bc6c5d 100644 --- a/bindings/py3devil1pld.py +++ b/bindings/py3devil1pld.py @@ -6,7 +6,7 @@ from .__init__ import libc # Basic Struct #--------------------------------------+ -class PldHeader(ctypes.Structure): +class _PldHeader_(ctypes.Structure): _pack_ = 1 _fields_ = [ ("numOffset", ctypes.c_int), @@ -17,14 +17,14 @@ class Devil1PLD_FN(ctypes.Structure): _fields_ = [ ("getheader" , ctypes.CFUNCTYPE( ctypes.c_bool, - ctypes.POINTER(PldHeader), + ctypes.POINTER(_PldHeader_), ctypes.c_char_p)), ("sizeofsector", ctypes.CFUNCTYPE( ctypes.c_int, - ctypes.POINTER(PldHeader), + ctypes.POINTER(_PldHeader_), ctypes.c_int)), ("printheader" , ctypes.CFUNCTYPE(None, - ctypes.POINTER(PldHeader))) + ctypes.POINTER(_PldHeader_))) ] devil1pld = Devil1PLD_FN.in_dll(libc, "DEVIL1PLD") @@ -34,10 +34,10 @@ del libc # Pythonic Object #--------------------------------------+ -class PLDHeader: +class PldHeader: def __init__(self, filedata = None): # Store C Struct in order to call C functions - self.cstruct = PldHeader() + self.cstruct = _PldHeader_() if filedata: devil1pld.getheader(ctypes.byref(self.cstruct), filedata) self.eof = len(filedata) From 43afe7bf70b24d5d7bbf9312ee85b1932108a065 Mon Sep 17 00:00:00 2001 From: surkeh Date: Wed, 16 May 2018 22:10:46 -0700 Subject: [PATCH 40/62] Cleanup: #!s, prints, exceptions, more consistent naming --- Makefile | 2 +- bindings/__init__.py | 6 +----- bindings/{main.py => __test__.py} | 27 ++++++++++++++------------- bindings/py3devil1geo.py | 11 +++++------ bindings/py3devil1pld.py | 14 +++++++------- bindings/py3devil1tex.py | 11 +++++------ 6 files changed, 33 insertions(+), 38 deletions(-) rename bindings/{main.py => __test__.py} (86%) mode change 100644 => 100755 diff --git a/Makefile b/Makefile index ee67998..9b199fb 100644 --- a/Makefile +++ b/Makefile @@ -35,4 +35,4 @@ devil1geo.o: src/devil1geo.c $(CC) -c $^ $(CFLAGS) clean: - rm *.o *.gch $(TARGET) $(PEX) $(TEX) $(MEX) + rm *.o $(TARGET) $(PEX) $(TEX) $(MEX) diff --git a/bindings/__init__.py b/bindings/__init__.py index 7262a68..dbbc6dc 100644 --- a/bindings/__init__.py +++ b/bindings/__init__.py @@ -3,11 +3,7 @@ import sys, ctypes sharedlib = './lib3ddevil1.so' libc = ctypes.cdll.LoadLibrary(sharedlib) if not libc: - print("Couldn't load %s" % sharedlib) - sys.exit() - -# Observe how many times the .so is loaded. -print("\nlib3ddevil1 loaded.") + raise SystemExit("Couldn't load %s" % sharedlib) # Don't need these anymore del sys, sharedlib diff --git a/bindings/main.py b/bindings/__test__.py old mode 100644 new mode 100755 similarity index 86% rename from bindings/main.py rename to bindings/__test__.py index 8659ea2..3953c65 --- a/bindings/main.py +++ b/bindings/__test__.py @@ -1,6 +1,7 @@ -from py3devil1pld import PldHeader -from py3devil1tex import TEXturePack, TEXtureBatchDescriptor, TEXtureBatch -from py3devil1geo import GEOHeader, MEShHeader, MEsh +#!/usr/bin/python3 +from py3devil1pld import pyPldHeader +from py3devil1tex import pyTexturePack, pyTextureBatchDescriptor, pyTextureBatch +from py3devil1geo import pyGeoHeader, pyMeshHeader, pyMesh #print(libc) @@ -54,7 +55,7 @@ if __name__ == "__main__": print("OK") pldfn = Devil1PLD_FN.in_dll(libc, "DEVIL1PLD") - pldh = PldHeader() + pldh = pyPldHeader() pldtest(pldfn, pldh) texfn = Devil1TEX_FN.in_dll(libc, "DEVIL1TEX") @@ -68,29 +69,29 @@ if __name__ == "__main__": def mainx(): with open("pl01.pld", "rb") as f: data = f.read() - pld = PldHeader(data) + pld = pyPldHeader(data) pld.show() - pld2 = PldHeader() + pld2 = pyPldHeader() pld2.show() with open("pl01.pld_1.txp", "rb") as f: data = f.read() - txp = TEXturePack(data) + txp = pyTexturePack(data) txp.show() print(txp.getbatchno()) print(txp.getfirstbatchoffset()) - tbd = TEXtureBatchDescriptor(1, data) + tbd = pyTextureBatchDescriptor(1, data) tbd.show() print(tbd.gettexturesize()) - #tx = TEXtures(0, tbd.gettexno(), data) - tx = TEXtureBatch(0, data) + #tx = pyTextures(0, tbd.gettexno(), data) + tx = pyTextureBatch(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 = pyGeoHeader(data) gh.show() print("-------------") print(gh.getmeshno()) @@ -99,9 +100,9 @@ if __name__ == "__main__": print(gh.getunknownd()) print(gh.getpadding()) print(gh.getunknownoffset()) - mh = MEShHeader(3, data) + mh = pyMeshHeader(3, data) mh.show() - m = MEsh(0, data) + m = pyMesh(0, data) m.show() # p = m.getpositions() # print("positions:") diff --git a/bindings/py3devil1geo.py b/bindings/py3devil1geo.py index 7d5ca1b..7388053 100644 --- a/bindings/py3devil1geo.py +++ b/bindings/py3devil1geo.py @@ -1,6 +1,5 @@ -#!/usr/bin/python3 import ctypes -from .__init__ import libc +from __init__ import libc #--------------------------------------+ # Basic Struct @@ -141,7 +140,7 @@ del libc # Pythonic Object #--------------------------------------+ -class GEOHeader: +class pyGeoHeader: def __init__(self, filedata): self.cstruct = ctypes.pointer(Header()) ptrofptr = ctypes.byref(self.cstruct) @@ -171,7 +170,7 @@ class GEOHeader: return hex(self.cstruct.contents.unknownOffset) -class MEShHeader: +class pyMeshHeader: def __init__(self, i, filedata): self.cstruct = ctypes.pointer(MeshHeader()) ptrofptr = ctypes.byref(self.cstruct) @@ -198,11 +197,11 @@ class MEShHeader: def getflags(self): return self.cstruct.contents.flags -class MEsh: +class pyMesh: def __init__(self, i, filedata): self.cstruct = Mesh() if filedata: - mh = MEShHeader(i, filedata) + mh = pyMeshHeader(i, filedata) # allocate memory for the size of batch * number of batches memsize = ctypes.sizeof(Batch) * mh.getbatchno() self.cstruct.b = ctypes.cast( diff --git a/bindings/py3devil1pld.py b/bindings/py3devil1pld.py index 8bc6c5d..958f8bd 100644 --- a/bindings/py3devil1pld.py +++ b/bindings/py3devil1pld.py @@ -1,12 +1,12 @@ #!/usr/bin/python3 import ctypes -from .__init__ import libc +from __init__ import libc #--------------------------------------+ # Basic Struct #--------------------------------------+ -class _PldHeader_(ctypes.Structure): +class PldHeader(ctypes.Structure): _pack_ = 1 _fields_ = [ ("numOffset", ctypes.c_int), @@ -17,14 +17,14 @@ class Devil1PLD_FN(ctypes.Structure): _fields_ = [ ("getheader" , ctypes.CFUNCTYPE( ctypes.c_bool, - ctypes.POINTER(_PldHeader_), + ctypes.POINTER(PldHeader), ctypes.c_char_p)), ("sizeofsector", ctypes.CFUNCTYPE( ctypes.c_int, - ctypes.POINTER(_PldHeader_), + ctypes.POINTER(PldHeader), ctypes.c_int)), ("printheader" , ctypes.CFUNCTYPE(None, - ctypes.POINTER(_PldHeader_))) + ctypes.POINTER(PldHeader))) ] devil1pld = Devil1PLD_FN.in_dll(libc, "DEVIL1PLD") @@ -34,10 +34,10 @@ del libc # Pythonic Object #--------------------------------------+ -class PldHeader: +class pyPldHeader: def __init__(self, filedata = None): # Store C Struct in order to call C functions - self.cstruct = _PldHeader_() + self.cstruct = PldHeader() if filedata: devil1pld.getheader(ctypes.byref(self.cstruct), filedata) self.eof = len(filedata) diff --git a/bindings/py3devil1tex.py b/bindings/py3devil1tex.py index 7ad661a..32aeb7f 100644 --- a/bindings/py3devil1tex.py +++ b/bindings/py3devil1tex.py @@ -1,6 +1,5 @@ -#!/usr/bin/python3 import ctypes -from .__init__ import libc +from __init__ import libc #--------------------------------------+ # Basic Struct @@ -80,7 +79,7 @@ del libc # Pythonic Object #--------------------------------------+ -class TEXturePack: +class pyTexturePack: def __init__(self, filedata): self.cstruct = ctypes.pointer(TexturePack()) devil1tex.getheader(ctypes.byref(self.cstruct), filedata) @@ -95,7 +94,7 @@ class TEXturePack: def getfirstbatchoffset(self): return self.cstruct.contents.firstBatchOffset -class TEXtureBatchDescriptor: +class pyTextureBatchDescriptor: def __init__(self, i, filedata): self.cstruct = ctypes.pointer(TextureBatchDescriptor()) ptrofptr = ctypes.byref(self.cstruct) @@ -118,12 +117,12 @@ class TEXtureBatchDescriptor: def gettexturesize(self): return self.cstruct.contents.textureSize -class TEXtureBatch: +class pyTextureBatch: def __init__(self, i, filedata): self.cstruct = TextureBatch() if filedata: self.cstruct.batch = None - tbd = TEXtureBatchDescriptor(i, filedata) + tbd = pyTextureBatchDescriptor(i, filedata) self.amount = tbd.gettexno() memsize = self.amount * tbd.gettexturesize() self.cstruct.batch = ctypes.cast( From 6ffe6f57ece7fbe246a0281390f9bd789668decb Mon Sep 17 00:00:00 2001 From: surkeh Date: Wed, 16 May 2018 22:32:43 -0700 Subject: [PATCH 41/62] Raise exception if python mesh fails to extract meshes --- bindings/py3devil1geo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/py3devil1geo.py b/bindings/py3devil1geo.py index 7388053..4102565 100644 --- a/bindings/py3devil1geo.py +++ b/bindings/py3devil1geo.py @@ -212,7 +212,7 @@ class pyMesh: i, filedata, len(filedata)): - print("failed to get mesh") + raise RuntimeError("failed to get mesh") del mh, memsize return From f4e5dfa269c9761094aea9bfa09294c5190ef9e4 Mon Sep 17 00:00:00 2001 From: surkeh Date: Thu, 17 May 2018 00:02:17 -0700 Subject: [PATCH 42/62] removed stray #! --- bindings/py3devil1pld.py | 1 - 1 file changed, 1 deletion(-) diff --git a/bindings/py3devil1pld.py b/bindings/py3devil1pld.py index 958f8bd..bb4d54c 100644 --- a/bindings/py3devil1pld.py +++ b/bindings/py3devil1pld.py @@ -1,4 +1,3 @@ -#!/usr/bin/python3 import ctypes from __init__ import libc From 4b574f94563f5cc873b4df494403ae1436d5c075 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Thu, 17 May 2018 11:08:58 -0700 Subject: [PATCH 43/62] Added raise RuntimeError blocks for all pyobjects in geo --- bindings/py3devil1geo.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bindings/py3devil1geo.py b/bindings/py3devil1geo.py index 4102565..fabf65d 100644 --- a/bindings/py3devil1geo.py +++ b/bindings/py3devil1geo.py @@ -145,7 +145,8 @@ class pyGeoHeader: self.cstruct = ctypes.pointer(Header()) ptrofptr = ctypes.byref(self.cstruct) if filedata: - devil1geo.getheader(ptrofptr, filedata) + if not devil1geo.getheader(ptrofptr, filedata): + raise RuntimeError("failed to get geometry file header") return def show(self): @@ -175,7 +176,8 @@ class pyMeshHeader: self.cstruct = ctypes.pointer(MeshHeader()) ptrofptr = ctypes.byref(self.cstruct) if filedata: - devil1geo.getmeshheader(ptrofptr, i, filedata) + if not devil1geo.getmeshheader(ptrofptr, i, filedata): + raise RuntimeError("failed to get mesh header #" + str(i)) return pass From 2c3aba370fc45ecf4e71086ad78f9c69a77164af Mon Sep 17 00:00:00 2001 From: _ <_> Date: Thu, 17 May 2018 11:14:24 -0700 Subject: [PATCH 44/62] Corrected return value for geo's getheader --- bindings/py3devil1geo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/py3devil1geo.py b/bindings/py3devil1geo.py index fabf65d..e1bdd9e 100644 --- a/bindings/py3devil1geo.py +++ b/bindings/py3devil1geo.py @@ -112,7 +112,7 @@ class Devil1GEO_FN(ctypes.Structure): None, ctypes.POINTER(Coordinate))), ("getheader", ctypes.CFUNCTYPE( - None, + ctypes.c_bool, ctypes.POINTER(ctypes.POINTER(Header)), ctypes.c_char_p)), ("getmeshheader", ctypes.CFUNCTYPE( From 201df8d366c099cc9d45319fe52c3d3a7818ed34 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Thu, 17 May 2018 11:26:01 -0700 Subject: [PATCH 45/62] Tested exceptions thrown --- bindings/__test__.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/bindings/__test__.py b/bindings/__test__.py index 3953c65..b3bf85d 100755 --- a/bindings/__test__.py +++ b/bindings/__test__.py @@ -101,6 +101,16 @@ if __name__ == "__main__": print(gh.getpadding()) print(gh.getunknownoffset()) mh = pyMeshHeader(3, data) + print("-------------") + try: + mh = pyMeshHeader(87, data) + except RuntimeError as e: + print(str(e)) + try: + mh = pyMesh(87, data) + except RuntimeError as e: + print(str(e)) + print("-------------") mh.show() m = pyMesh(0, data) m.show() From cef4720e42d2b0d21cb3a35b51c0843f44789129 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Thu, 17 May 2018 11:35:19 -0700 Subject: [PATCH 46/62] Added exceptions for pld getheader() --- bindings/py3devil1pld.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bindings/py3devil1pld.py b/bindings/py3devil1pld.py index bb4d54c..62ed79b 100644 --- a/bindings/py3devil1pld.py +++ b/bindings/py3devil1pld.py @@ -38,7 +38,8 @@ class pyPldHeader: # Store C Struct in order to call C functions self.cstruct = PldHeader() if filedata: - devil1pld.getheader(ctypes.byref(self.cstruct), filedata) + if not devil1pld.getheader(ctypes.byref(self.cstruct), filedata): + raise RuntimeError("failed to get .pld header") self.eof = len(filedata) def show(self): From 53ec9b04748bd1e7d9e7faeb7a6e3cbbd8498059 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Thu, 17 May 2018 11:35:43 -0700 Subject: [PATCH 47/62] Added exceptions for textures objects --- bindings/py3devil1tex.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/bindings/py3devil1tex.py b/bindings/py3devil1tex.py index 32aeb7f..6300ed1 100644 --- a/bindings/py3devil1tex.py +++ b/bindings/py3devil1tex.py @@ -82,7 +82,8 @@ del libc class pyTexturePack: def __init__(self, filedata): self.cstruct = ctypes.pointer(TexturePack()) - devil1tex.getheader(ctypes.byref(self.cstruct), filedata) + if not devil1tex.getheader(ctypes.byref(self.cstruct), filedata): + raise RuntimeError("failed to get texture pack header") return def show(self): @@ -99,7 +100,12 @@ class pyTextureBatchDescriptor: self.cstruct = ctypes.pointer(TextureBatchDescriptor()) ptrofptr = ctypes.byref(self.cstruct) if filedata: - devil1tex.getbatchdesc(ptrofptr, i, filedata, len(filedata)) + if not devil1tex.getbatchdesc( + ptrofptr, + i, + filedata, + len(filedata)): + raise RuntimeError("failed to get texturebatchdescriptor #" + str(i)) return def show(self): @@ -128,7 +134,12 @@ class pyTextureBatch: self.cstruct.batch = ctypes.cast( ctypes.create_string_buffer(memsize), ctypes.POINTER(Texture)) - devil1tex.gettextures(self.cstruct.batch, i, filedata, len(filedata)) + 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): From a2d91cd56b317f91a96d4b494762fe5e75153258 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Thu, 17 May 2018 12:01:16 -0700 Subject: [PATCH 48/62] Handled exception where .so can not be loaded. --- bindings/__init__.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/bindings/__init__.py b/bindings/__init__.py index dbbc6dc..a5d2c47 100644 --- a/bindings/__init__.py +++ b/bindings/__init__.py @@ -1,9 +1,11 @@ -import sys, ctypes +import ctypes sharedlib = './lib3ddevil1.so' -libc = ctypes.cdll.LoadLibrary(sharedlib) -if not libc: +try: + libc = ctypes.cdll.LoadLibrary(sharedlib) +except OSError as e: + print("Error loading dynamically linked library.\nOSError: " + str(e)) raise SystemExit("Couldn't load %s" % sharedlib) # Don't need these anymore -del sys, sharedlib +del sharedlib From 360de0dea55f86c52abd24c5e1e03d9a790f2a8e Mon Sep 17 00:00:00 2001 From: _ <_> Date: Thu, 17 May 2018 14:00:52 -0700 Subject: [PATCH 49/62] declared function where del sharedlib is not needed anymore --- bindings/__init__.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/bindings/__init__.py b/bindings/__init__.py index a5d2c47..b49dc36 100644 --- a/bindings/__init__.py +++ b/bindings/__init__.py @@ -1,11 +1,12 @@ import ctypes -sharedlib = './lib3ddevil1.so' -try: - libc = ctypes.cdll.LoadLibrary(sharedlib) -except OSError as e: - print("Error loading dynamically linked library.\nOSError: " + str(e)) - raise SystemExit("Couldn't load %s" % sharedlib) +def loadlibc(): + sharedlib = './lib3ddevil1.so' + libc = None + try: + libc = ctypes.cdll.LoadLibrary(sharedlib) + except OSError as e: + print("Error loading dynamically linked library.\nOSError: " + str(e)) + raise SystemExit("Couldn't load %s" % sharedlib) -# Don't need these anymore -del sharedlib +libc = loadlibc() \ No newline at end of file From 911a1ad840010ea8d8f8c5e422b14ba3287c8423 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Thu, 17 May 2018 15:07:17 -0700 Subject: [PATCH 50/62] Added return statement for fn in __init__ --- bindings/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bindings/__init__.py b/bindings/__init__.py index b49dc36..6a1ff15 100644 --- a/bindings/__init__.py +++ b/bindings/__init__.py @@ -8,5 +8,6 @@ def loadlibc(): except OSError as e: print("Error loading dynamically linked library.\nOSError: " + str(e)) raise SystemExit("Couldn't load %s" % sharedlib) + return libc libc = loadlibc() \ No newline at end of file From 9b9f0bd6ee316b78a824e3e2a7b37103cfb48b92 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Thu, 17 May 2018 15:20:39 -0700 Subject: [PATCH 51/62] Fixed issues caused by importing from __init__ statements --- bindings/py3devil1geo.py | 8 +++++++- bindings/py3devil1pld.py | 9 ++++++++- bindings/py3devil1tex.py | 8 +++++++- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/bindings/py3devil1geo.py b/bindings/py3devil1geo.py index e1bdd9e..5757b6a 100644 --- a/bindings/py3devil1geo.py +++ b/bindings/py3devil1geo.py @@ -1,5 +1,11 @@ import ctypes -from __init__ import libc +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 diff --git a/bindings/py3devil1pld.py b/bindings/py3devil1pld.py index 62ed79b..a16c8c5 100644 --- a/bindings/py3devil1pld.py +++ b/bindings/py3devil1pld.py @@ -1,5 +1,12 @@ import ctypes -from __init__ import libc +import os, sys +# This is the folder containing the whole library. +sys.path.append( + os.path.abspath( + os.path.join( + os.path.dirname(__file__), "../../"))) +from lib3ddevil1.bindings import libc +del os, sys #--------------------------------------+ # Basic Struct diff --git a/bindings/py3devil1tex.py b/bindings/py3devil1tex.py index 6300ed1..4c67368 100644 --- a/bindings/py3devil1tex.py +++ b/bindings/py3devil1tex.py @@ -1,5 +1,11 @@ import ctypes -from __init__ import libc +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 From e63ddfb8383a1fd753a1cb1287a9a24eb64e2bc8 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Thu, 17 May 2018 15:28:28 -0700 Subject: [PATCH 52/62] Added library to path to search for .so --- bindings/__init__.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/bindings/__init__.py b/bindings/__init__.py index 6a1ff15..9675198 100644 --- a/bindings/__init__.py +++ b/bindings/__init__.py @@ -1,8 +1,13 @@ -import ctypes +import ctypes, os, sys def loadlibc(): sharedlib = './lib3ddevil1.so' libc = None + os.environ['PATH'] = os.path.abspath( + os.path.join( + os.path.dirname(__file__), "../")) \ + + ';' \ + + os.environ['PATH'] try: libc = ctypes.cdll.LoadLibrary(sharedlib) except OSError as e: @@ -10,4 +15,4 @@ def loadlibc(): raise SystemExit("Couldn't load %s" % sharedlib) return libc -libc = loadlibc() \ No newline at end of file +libc = loadlibc() From 058e395735553c0768983ee1d15edf1f13ffa00e Mon Sep 17 00:00:00 2001 From: _ <_> Date: Thu, 17 May 2018 16:30:01 -0700 Subject: [PATCH 53/62] Added consistent naming for methods for geo --- bindings/__test__.py | 2 +- bindings/py3devil1geo.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bindings/__test__.py b/bindings/__test__.py index b3bf85d..df445d8 100755 --- a/bindings/__test__.py +++ b/bindings/__test__.py @@ -94,7 +94,7 @@ if __name__ == "__main__": gh = pyGeoHeader(data) gh.show() print("-------------") - print(gh.getmeshno()) + print(gh.getnummesh()) print(gh.getunknownb()) print(gh.getunknownc()) print(gh.getunknownd()) diff --git a/bindings/py3devil1geo.py b/bindings/py3devil1geo.py index 5757b6a..43c4803 100644 --- a/bindings/py3devil1geo.py +++ b/bindings/py3devil1geo.py @@ -158,7 +158,7 @@ class pyGeoHeader: def show(self): devil1geo.printheader(self.cstruct) - def getmeshno(self): + def getnummesh(self): return self.cstruct.contents.numMesh def getunknownb(self): @@ -190,7 +190,7 @@ class pyMeshHeader: def show(self): devil1geo.printmeshheader(self.cstruct) - def getbatchno(self): + def getnumbatch(self): return self.cstruct.contents.numBatch def getnumvertex(self): @@ -211,7 +211,7 @@ class pyMesh: if filedata: mh = pyMeshHeader(i, filedata) # allocate memory for the size of batch * number of batches - memsize = ctypes.sizeof(Batch) * mh.getbatchno() + memsize = ctypes.sizeof(Batch) * mh.getnumbatch() self.cstruct.b = ctypes.cast( ctypes.create_string_buffer(memsize), ctypes.POINTER(Batch)) From 6b5931c9799a619af02a5cc809c01f4081726504 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Thu, 17 May 2018 16:34:07 -0700 Subject: [PATCH 54/62] Added consistent names for methods for textures --- bindings/py3devil1tex.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bindings/py3devil1tex.py b/bindings/py3devil1tex.py index 4c67368..6125cdd 100644 --- a/bindings/py3devil1tex.py +++ b/bindings/py3devil1tex.py @@ -95,7 +95,7 @@ class pyTexturePack: def show(self): devil1tex.printheader(self.cstruct) - def getbatchno(self): + def getbatchnumber(self): return self.cstruct.contents.batchNumber def getfirstbatchoffset(self): @@ -123,7 +123,7 @@ class pyTextureBatchDescriptor: def gethash(self): return self.cstruct.contents.hash - def gettexno(self): + def gettexnumber(self): return self.cstruct.contents.texNumber def gettexturesize(self): From 95836e0dfa4bafa631948827acc3ddd2c83b2227 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Thu, 17 May 2018 16:46:13 -0700 Subject: [PATCH 55/62] Fixed unupdated name --- bindings/py3devil1tex.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/py3devil1tex.py b/bindings/py3devil1tex.py index 6125cdd..1e77a24 100644 --- a/bindings/py3devil1tex.py +++ b/bindings/py3devil1tex.py @@ -135,7 +135,7 @@ class pyTextureBatch: if filedata: self.cstruct.batch = None tbd = pyTextureBatchDescriptor(i, filedata) - self.amount = tbd.gettexno() + self.amount = tbd.gettexnumber() memsize = self.amount * tbd.gettexturesize() self.cstruct.batch = ctypes.cast( ctypes.create_string_buffer(memsize), From 979c5f4aaadcb3817aae840d7a9ca8e4fcec9f7a Mon Sep 17 00:00:00 2001 From: _ <_> Date: Thu, 17 May 2018 16:46:45 -0700 Subject: [PATCH 56/62] Updated fn call in test --- bindings/__test__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/__test__.py b/bindings/__test__.py index df445d8..7550080 100755 --- a/bindings/__test__.py +++ b/bindings/__test__.py @@ -78,7 +78,7 @@ if __name__ == "__main__": data = f.read() txp = pyTexturePack(data) txp.show() - print(txp.getbatchno()) + print(txp.getbatchnumber()) print(txp.getfirstbatchoffset()) tbd = pyTextureBatchDescriptor(1, data) tbd.show() From e63154cd7f8cfbb940a172bd0fd48ebe3386e8d5 Mon Sep 17 00:00:00 2001 From: surkeh Date: Thu, 17 May 2018 16:58:45 -0700 Subject: [PATCH 57/62] Changed SystemExit exception to RuntimeError --- bindings/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/__init__.py b/bindings/__init__.py index 9675198..ee86a27 100644 --- a/bindings/__init__.py +++ b/bindings/__init__.py @@ -12,7 +12,7 @@ def loadlibc(): libc = ctypes.cdll.LoadLibrary(sharedlib) except OSError as e: print("Error loading dynamically linked library.\nOSError: " + str(e)) - raise SystemExit("Couldn't load %s" % sharedlib) + raise RuntimeError("Couldn't load %s" % sharedlib) return libc libc = loadlibc() From b45ab07aa5344cf2fc7e6c6f48bd83fdce23583d Mon Sep 17 00:00:00 2001 From: _ <_> Date: Thu, 17 May 2018 21:54:34 -0700 Subject: [PATCH 58/62] Wrote documentation for the python interface --- docs/doc-python.txt | 242 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 docs/doc-python.txt diff --git a/docs/doc-python.txt b/docs/doc-python.txt new file mode 100644 index 0000000..53cbe15 --- /dev/null +++ b/docs/doc-python.txt @@ -0,0 +1,242 @@ + +lib3ddevil1/bindings +Python interface to C library functions of lib3ddevil1. + +This component uses ctypes thus it must access a compiled .so file (internally +a .dll for Windows). The .so may be located in the top level of the library +directory or any directory in the environment variable's path. + +Note that there are two categories of objects in each python interface. One is +derived from ctypes.Structure, and the other is a pythonic object. The former +is for internal use and requires knowledge of both python, C, and ctypes. The +latter is to be used by python users. + +Functions and Objects + class pyPldHeader + def __init__(self, filedata = None): + parameters: file data, is a single line list of data. + + This function may raise RuntimeError when it fails to initialize + based on file data. + + def show(self): + This prints the contents of the object. + + def getnumoffsets(self): + This returns the attribute numOffsets of a PldHeader. + See details of the C struct in doc-pld.txt. + + def getoffsets(self): + This returns a pythonic list of offsets. + The offsets can be accessed via list comprehensions. + + def sizeofsector(self, i): + parameter: i, an integer. + This returns the size of the i-th sector in the .pld. + + If the result is -1, then specified i is out of range. + + class PyTexturePack + def __init__(self, filedata): + parameters: file data, a single line list of data. + + This function may raise RuntimeError when it fails to initialize + based on file data. + + See details of the C struct in doc-tex.txt. + + def show(self): + This prints the contents of the object. + + def getbatchnumber(self): + This returns the attribute 'batchNumber'. + + def getfirstbatchoffset(self): + This returns the attribute 'firstBatchOffset'. + + class pyTextureBatchDescriptor: + def __init__(self, i, filedata): + parameters: i, for i-th instance of TextureBatchDescriptor. + filedata, a single line list of data. + + This function may raise RuntimeError when it fails to initialize + based on file data. + + See details of the C struct in doc-tex.txt. + + def show(self): + This prints the contents of the object. + + def getbatchidx(self): + This returns the attribute 'batchidx'. + + def gethash(self): + This returns the attribute 'hash'. + + def gettexnumber(self): + This returns the attribute 'texNumber'. + + def gettexturesize(self): + This returns the attribute 'textureSize'. + + class pyTextureBatch: + def __init__(self, i, filedata): + parameters: i, for i-th instance of TextureBatch. + file data, a single line list of data. + + This function may raise RuntimeError when it fails to initialize + based on file data. + + See details of the C struct in doc-tex.txt. + + def gettextures(self): + This returns a pythonic list of texture data. + The textures can be accessed via list comprehensions. + + class pyGeoHeader: + def __init__(self, filedata): + parameters: file data, a single line list of data. + + This function may raise RuntimeError when it fails to initialize + based on file data. + + See details of the C struct in doc-geo.txt. + + def show(self): + This prints the contents of the object. + + def getnummesh(self): + This returns the attribute 'numMesh'. + + def getunknownb(self): + This returns the attribute 'unknownNumberB'. + + def getunknownc(self): + This returns the attribute 'unknownNumberC'. + + def getunknownd(self): + This returns the attribute 'unknownNumberD'. + + def getpadding(self): + This returns the attribute 'padding'. + + def getunknownoffset(self): + This returns the attribute 'unknownOffset'. + + class pyMeshHeader: + def __init__(self, i, filedata): + + def show(self): + This prints the contents of the object. + + def getnumbatch(self): + This returns the attribute 'numBatch'. + + def getnumvertex(self): + This returns the attribute 'numVertex'. + + def getunknown(self): + This returns the attribute 'u'. + + def getoffsetbatches(self): + This returns the attribute 'offsetBatches'. + + def getflags(self): + This returns the attribute 'flags'. + + class pyMesh: + def __init__(self, i, filedata): + parameters: i, for i-th instance of Mesh. + filedata, a single line list of data. + + This function may raise RuntimeError when it fails to initialize + based on file data. + + See details of the C struct in doc-geo.txt. + + def show(self): + This prints the contents of the object. + + def getbatchdata(self): + This returns the attribute 'bd'. + It is a object without methods, and it's attributes are + conventionally accessed with the '.' operator. + + def getpositions(self): + This returns a pythonic list of 'positions'. + The positions can be accessed with list comprehensions. + + A position is a object 'Coordinate' without methods. + The attributes are x, y, and z to be accessed with the + '.' operator. + + def getnormals(self): + This returns a pythonic list of 'normals'. + The normals can be accessed with list comprehensions. + + A normal is a object 'Coordinate' without methods. + The attributes are x, y, and z to be accessed with the + '.' operator. + + def getuvs(self): + This returns a pythonic list of 'u'. + The UVs can be accessed with list comprehensions. + + A UV has two attributes, 'u' and 'v'. + + def getboneindexes(self): + This returns a pythonic list of 'bi'. + The bone indices can be accessed with list comprehensions. + + A bone index is a fixed length array of 4 elements, unsigned byte. + + def getboneweights(self): + This returns a pythonic list of 'bw'. + The bone weights can be accessed with list comprehensions. + + A bone weight is effectively an integer in python. + +Example Logic: Extract Pld's + with open("pl01.pld", "rb") as f: + data = f.read() + pld = pyPldHeader(data) + filename = "demonstrate" + i = 0 + for offset in pld.getoffsets(): + with open(filename + str(i), "wb") as fw: + end = offset + pld.sizeofsector(i) + chunk = data[offset:end] + fw.write(chunk) + i += 1 + +Example Logic: Extract Textures + from ctypes import * + with open("pl01.pld_1.txp", "rb") as f: + data = f.read() + tx = pyTextureBatch(0, data) + filename = "texture" + i = 0 + bd = pyTextureBatchDescriptor(i, data) + size = bd.gettexturesize() + for texture in tx.gettextures(): + with open(filename + str(i) + ".dds", "wb") as fw: + image = cast(texture.data, POINTER(c_ubyte * size))[0] + fw.write(image) + i += 1 + +Example Logic: Iterate through all MeshHeaders and Meshes: + with open("pl00.pld_0", "rb") as f: + # Get data to extract from. + data = f.read() + # We want to know how many meshes are in the file. + gh = pyGeoHeader(data) + # Show each MeshHeader + for i in range(0, gh.getnummesh()): + mh = pyMeshHeader(i, data) + mh.show() + # Get each Mesh + for i in range(0, gh.getnummesh()): + m = pyMesh(i, data) + m.show() + # Whatever you do with each of them is up to you. + From 52de706a96760419a6b634281d02e022ccb9d437 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Thu, 17 May 2018 22:44:00 -0700 Subject: [PATCH 59/62] gettextures() returns list of writable byte arrays --- bindings/py3devil1tex.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/bindings/py3devil1tex.py b/bindings/py3devil1tex.py index 1e77a24..dccf093 100644 --- a/bindings/py3devil1tex.py +++ b/bindings/py3devil1tex.py @@ -136,7 +136,8 @@ class pyTextureBatch: self.cstruct.batch = None tbd = pyTextureBatchDescriptor(i, filedata) self.amount = tbd.gettexnumber() - memsize = self.amount * tbd.gettexturesize() + self.size = tbd.gettexturesize() + memsize = self.amount * self.size self.cstruct.batch = ctypes.cast( ctypes.create_string_buffer(memsize), ctypes.POINTER(Texture)) @@ -149,5 +150,12 @@ class pyTextureBatch: return def gettextures(self): - return self.cstruct.batch[:self.amount] + 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 From 549105e5367730edc991551602abf96088ee18d1 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Fri, 18 May 2018 01:48:10 -0700 Subject: [PATCH 60/62] Updated example for current version of python interface --- docs/doc-python.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/doc-python.txt b/docs/doc-python.txt index 53cbe15..0c813a0 100644 --- a/docs/doc-python.txt +++ b/docs/doc-python.txt @@ -220,8 +220,7 @@ Example Logic: Extract Textures size = bd.gettexturesize() for texture in tx.gettextures(): with open(filename + str(i) + ".dds", "wb") as fw: - image = cast(texture.data, POINTER(c_ubyte * size))[0] - fw.write(image) + fw.write(texture) i += 1 Example Logic: Iterate through all MeshHeaders and Meshes: From f34289def982afe760808daa9af06a183ddeeaaa Mon Sep 17 00:00:00 2001 From: _ <_> Date: Fri, 18 May 2018 01:58:18 -0700 Subject: [PATCH 61/62] Updated texture example to iterate through all textures. --- docs/doc-python.txt | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/docs/doc-python.txt b/docs/doc-python.txt index 0c813a0..6324206 100644 --- a/docs/doc-python.txt +++ b/docs/doc-python.txt @@ -209,19 +209,21 @@ Example Logic: Extract Pld's fw.write(chunk) i += 1 -Example Logic: Extract Textures - from ctypes import * +Example Logic: Extract Textures from a Single Batch with open("pl01.pld_1.txp", "rb") as f: data = f.read() - tx = pyTextureBatch(0, data) - filename = "texture" - i = 0 - bd = pyTextureBatchDescriptor(i, data) - size = bd.gettexturesize() - for texture in tx.gettextures(): - with open(filename + str(i) + ".dds", "wb") as fw: - fw.write(texture) - i += 1 + tp = pyTexturePack(data) + filename = "texture" # part 1 of output file name + id = 0 # part 2 of output file name + # Iterate through all of the batches in the package. + for i in range(0, tp.getbatchnumber()): + # Get a batch. + tx = pyTextureBatch(i, data) + # Iterate through all textures in batch. + for texture in tx.gettextures(): + with open(filename + str(id) + ".dds", "wb") as fw: + fw.write(texture) + id += 1 Example Logic: Iterate through all MeshHeaders and Meshes: with open("pl00.pld_0", "rb") as f: From 27a43e5943b0f268ffd4b47516faae3086fe3627 Mon Sep 17 00:00:00 2001 From: _ <_> Date: Fri, 18 May 2018 16:49:06 -0700 Subject: [PATCH 62/62] Removed path manipulations for single absolute path to build location of .so --- bindings/__init__.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/bindings/__init__.py b/bindings/__init__.py index ee86a27..75322a0 100644 --- a/bindings/__init__.py +++ b/bindings/__init__.py @@ -1,13 +1,18 @@ import ctypes, os, sys def loadlibc(): - sharedlib = './lib3ddevil1.so' libc = None - os.environ['PATH'] = os.path.abspath( - os.path.join( - os.path.dirname(__file__), "../")) \ - + ';' \ - + os.environ['PATH'] +# os.environ['PATH'] = os.path.abspath( +# os.path.join( +# os.path.dirname(__file__), "../")) \ +# + ';' \ +# + os.environ['PATH'] + # __file__ is this __init__.py + # This assumes that the repo's directory has not been modified + # and that + so = '/lib3ddevil1.so' + libdir = os.path.abspath(os.path.join(os.path.dirname(__file__), "../")) + sharedlib = libdir + so try: libc = ctypes.cdll.LoadLibrary(sharedlib) except OSError as e: