Merge branch 'python/finalize' of https://git.teknik.io/scuti/lib3ddevil1 into feature/documentation

This commit is contained in:
_ 2018-05-17 17:56:19 -07:00
commit 8b1142e31d
13 changed files with 681 additions and 20 deletions

4
.gitignore vendored
View File

@ -1,9 +1,11 @@
# Files from compilation and tests
*.o
*.so
*.gch
*.exe
*.stackdump
*.log
devil1test
__pycache__
demo-extractpld
demo-extracttexture
demo-extractmesh

View File

@ -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
all: pld texture mesh
$(TARGET): $(OBJ)
$(LINK.cc) $(LDFLAGS) $^ -o $@
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)

18
bindings/__init__.py Normal file
View File

@ -0,0 +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']
try:
libc = ctypes.cdll.LoadLibrary(sharedlib)
except OSError as e:
print("Error loading dynamically linked library.\nOSError: " + str(e))
raise RuntimeError("Couldn't load %s" % sharedlib)
return libc
libc = loadlibc()

134
bindings/__test__.py Executable file
View File

@ -0,0 +1,134 @@
#!/usr/bin/python3
from py3devil1pld import pyPldHeader
from py3devil1tex import pyTexturePack, pyTextureBatchDescriptor, pyTextureBatch
from py3devil1geo import pyGeoHeader, pyMeshHeader, pyMesh
#print(libc)
#--------------------------------------+
# 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 = pyPldHeader()
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 = pyPldHeader(data)
pld.show()
pld2 = pyPldHeader()
pld2.show()
with open("pl01.pld_1.txp", "rb") as f:
data = f.read()
txp = pyTexturePack(data)
txp.show()
print(txp.getbatchnumber())
print(txp.getfirstbatchoffset())
tbd = pyTextureBatchDescriptor(1, data)
tbd.show()
print(tbd.gettexturesize())
#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 = pyGeoHeader(data)
gh.show()
print("-------------")
print(gh.getnummesh())
print(gh.getunknownb())
print(gh.getunknownc())
print(gh.getunknownd())
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()
# p = m.getpositions()
# print("positions:")
# for point in p:
# print(point)
# n = m.getnormals()
# print("normals:")
# for point in n:
# print(point)
# u = m.getuvs()
# print("uvs:")
# for point in u:
# print(point)
dbatch = m.getbatchdata()
print(hex(dbatch.numVertex))
print(hex(dbatch.padding))
#---------------------------------------+
# main()
mainx()

254
bindings/py3devil1geo.py Normal file
View File

@ -0,0 +1,254 @@
import ctypes
import os, sys
sys.path.append(
os.path.abspath(
os.path.join(
os.path.dirname(__file__), "../../")))
from lib3ddevil1.bindings import libc
del os, sys
#--------------------------------------+
# Basic Struct
#--------------------------------------+
class 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(
ctypes.c_bool,
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")
del libc
#--------------------------------------+
# Pythonic Object
#--------------------------------------+
class pyGeoHeader:
def __init__(self, filedata):
self.cstruct = ctypes.pointer(Header())
ptrofptr = ctypes.byref(self.cstruct)
if filedata:
if not devil1geo.getheader(ptrofptr, filedata):
raise RuntimeError("failed to get geometry file header")
return
def show(self):
devil1geo.printheader(self.cstruct)
def getnummesh(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 pyMeshHeader:
def __init__(self, i, filedata):
self.cstruct = ctypes.pointer(MeshHeader())
ptrofptr = ctypes.byref(self.cstruct)
if filedata:
if not devil1geo.getmeshheader(ptrofptr, i, filedata):
raise RuntimeError("failed to get mesh header #" + str(i))
return
pass
def show(self):
devil1geo.printmeshheader(self.cstruct)
def getnumbatch(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 pyMesh:
def __init__(self, i, filedata):
self.cstruct = Mesh()
if filedata:
mh = pyMeshHeader(i, filedata)
# allocate memory for the size of batch * number of batches
memsize = ctypes.sizeof(Batch) * mh.getnumbatch()
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)):
raise RuntimeError("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]

66
bindings/py3devil1pld.py Normal file
View File

@ -0,0 +1,66 @@
import ctypes
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
#--------------------------------------+
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")
del libc
#--------------------------------------+
# Pythonic Object
#--------------------------------------+
class pyPldHeader:
def __init__(self, filedata = None):
# Store C Struct in order to call C functions
self.cstruct = PldHeader()
if filedata:
if not devil1pld.getheader(ctypes.byref(self.cstruct), filedata):
raise RuntimeError("failed to get .pld header")
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)

153
bindings/py3devil1tex.py Normal file
View File

@ -0,0 +1,153 @@
import ctypes
import os, sys
sys.path.append(
os.path.abspath(
os.path.join(
os.path.dirname(__file__), "../../")))
from lib3ddevil1.bindings import libc
del os, sys
#--------------------------------------+
# Basic Struct
#--------------------------------------+
class TexturePack(ctypes.Structure):
_pack_ = 1
_fields_ = [
("id", ctypes.c_char * 4), # fixed length 4, reverse order
("batchNumber", ctypes.c_int),
("firstBatchOffset", ctypes.c_int),
("unknownA", ctypes.c_int)
]
class TextureBatchDescriptor(ctypes.Structure):
_pack_ = 1
_fields_ = [
("batchIdx", ctypes.c_int),
("hash", ctypes.c_int),
("texNumber", ctypes.c_int),
("unknownA", ctypes.c_int * 8),
("textureSize", ctypes.c_int),
("unknownB", ctypes.c_int * 30)
]
class Texture(ctypes.Structure):
_pack_ = 1
_fields_ = [
("data", ctypes.POINTER(ctypes.c_ubyte))
]
class TextureBatch(ctypes.Structure):
_pack_ = 1
_fields_ = [
("batch", ctypes.POINTER(Texture))
]
class Devil1TEX_FN(ctypes.Structure):
_fields_ = [
("printheader", ctypes.CFUNCTYPE(
None,
ctypes.POINTER(TexturePack))),
("printbatchdesc", ctypes.CFUNCTYPE(
None,
ctypes.POINTER(TextureBatchDescriptor))),
("getheader", ctypes.CFUNCTYPE(
ctypes.c_bool,
ctypes.POINTER(
ctypes.POINTER(TexturePack)),
ctypes.c_char_p)),
("getbatchdesc", ctypes.CFUNCTYPE(
ctypes.c_bool,
ctypes.POINTER(
ctypes.POINTER(TextureBatchDescriptor)),
ctypes.c_uint,
ctypes.c_char_p,
ctypes.c_uint)),
("getbatch", ctypes.CFUNCTYPE(
ctypes.c_bool,
ctypes.POINTER(
ctypes.POINTER(TextureBatch)),
ctypes.c_uint,
ctypes.c_char_p,
ctypes.c_uint)),
("gettextures", ctypes.CFUNCTYPE(
ctypes.c_bool,
ctypes.POINTER(Texture),
ctypes.c_uint,
ctypes.c_char_p,
ctypes.c_uint))
]
devil1tex = Devil1TEX_FN.in_dll(libc, "DEVIL1TEX")
del libc
#--------------------------------------+
# Pythonic Object
#--------------------------------------+
class pyTexturePack:
def __init__(self, filedata):
self.cstruct = ctypes.pointer(TexturePack())
if not devil1tex.getheader(ctypes.byref(self.cstruct), filedata):
raise RuntimeError("failed to get texture pack header")
return
def show(self):
devil1tex.printheader(self.cstruct)
def getbatchnumber(self):
return self.cstruct.contents.batchNumber
def getfirstbatchoffset(self):
return self.cstruct.contents.firstBatchOffset
class pyTextureBatchDescriptor:
def __init__(self, i, filedata):
self.cstruct = ctypes.pointer(TextureBatchDescriptor())
ptrofptr = ctypes.byref(self.cstruct)
if filedata:
if not devil1tex.getbatchdesc(
ptrofptr,
i,
filedata,
len(filedata)):
raise RuntimeError("failed to get texturebatchdescriptor #" + str(i))
return
def show(self):
devil1tex.printbatchdesc(self.cstruct)
def getbatchidx(self):
return self.cstruct.contents.batchIdx
def gethash(self):
return self.cstruct.contents.hash
def gettexnumber(self):
return self.cstruct.contents.texNumber
def gettexturesize(self):
return self.cstruct.contents.textureSize
class pyTextureBatch:
def __init__(self, i, filedata):
self.cstruct = TextureBatch()
if filedata:
self.cstruct.batch = None
tbd = pyTextureBatchDescriptor(i, filedata)
self.amount = tbd.gettexnumber()
memsize = self.amount * tbd.gettexturesize()
self.cstruct.batch = ctypes.cast(
ctypes.create_string_buffer(memsize),
ctypes.POINTER(Texture))
if not devil1tex.gettextures(
self.cstruct.batch,
i,
filedata,
len(filedata)):
raise RuntimeError("failed to get textures of batch #" + str(i))
return
def gettextures(self):
return self.cstruct.batch[:self.amount]

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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**,

View File

@ -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,14 +76,22 @@ 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) {
bool done = false;
if (hs == NULL || filedata == NULL) {
struct Header *h = NULL;
if (hs == NULL || !(getgheader(&h, filedata))) {
return done;
}
struct Header *h = (struct Header*)filedata;
if (h -> numMesh < i) {
return done;
}

View File

@ -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 inline 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) {
}
}
inline 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,
@ -75,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;
}