From 15252083a75f579d6dc8492632f3631c6ba35ba5 Mon Sep 17 00:00:00 2001 From: Benjamin Collins Date: Sat, 22 Aug 2020 18:10:50 +0900 Subject: [PATCH] pvr twiddled rectangle --- NinjaModel.py | 11 ------ NinjaMotion.py | 2 -- PowerVR.py | 92 +++++++++++++++++++++++++++++++++++++++++++++++++- __init__.py | 32 ++++++++++++++++++ 4 files changed, 123 insertions(+), 14 deletions(-) diff --git a/NinjaModel.py b/NinjaModel.py index 533452e..c713daa 100644 --- a/NinjaModel.py +++ b/NinjaModel.py @@ -92,7 +92,6 @@ class NinjaModel: self.readNjcm(None) self.file.seek(pos, 0) elif (bytes == b'NMDM') : - print('Found Ninja Direct Motion') bytes = self.file.read(4) length = struct.unpack('I', bytes)[0] pos = self.file.tell() + length @@ -159,7 +158,6 @@ class NinjaModel: parentBone.add(self.bone) if model_ofs: - print("Reading model for Bone: %s" % self.bone.name) self.file.seek(model_ofs + self.pof, 0) self.readModel() @@ -235,15 +233,10 @@ class NinjaModel: if chunk_head != 255: print("ERROR ANOTHER VERTEX LIST DETECTED") - print("End Chunk Head: %d" % chunk_head) - print("End Chunk Flag: %d" % chunk_flag) return None def readChunkList(self): - print("---- Reading Chunk List ---") - print("Chunk Offset: 0x%08x" % self.file.tell()) - while 1: bytes = self.file.read(2) @@ -413,8 +406,6 @@ class NinjaModel: self.strip_count = self.strip_count + 1 else: - print("Unknown Chunk Type %d" % chunk_head) - print("Unknown Chunk Flag %d" % chunk_flag) print("Unknown File Position: 0x%08x" % self.file.tell()) #end While @@ -479,7 +470,6 @@ class NinjaModel: p = struct.unpack('I', bytes) entry['pos_num'] = p[0] - print("Row Offset: 0x%08x" % self.file.tell()) bytes = self.file.read(4) p = struct.unpack('I', bytes) entry['rot_num'] = p[0] @@ -493,7 +483,6 @@ class NinjaModel: for entry in anim_vals: boneIndex = entry['bone_index'] - print("Bone Index: %d" % boneIndex) self.file.seek(entry['pos_ofs'], 0) for i in range(entry['pos_num']): diff --git a/NinjaMotion.py b/NinjaMotion.py index 5a4832a..6f3ab6d 100644 --- a/NinjaMotion.py +++ b/NinjaMotion.py @@ -191,6 +191,4 @@ class NinjaMotion: file.write(struct.pack('f', 1)) file.write(struct.pack('f', 1)) - print(keyFrame) - return None diff --git a/PowerVR.py b/PowerVR.py index 719105c..3d7e5f0 100644 --- a/PowerVR.py +++ b/PowerVR.py @@ -67,7 +67,8 @@ class PowerVR: # { def __init__(self, filename): # { # File Information - + + self.debug = False base = os.path.basename(filename) self.name = os.path.splitext(base)[0] print(self.name) @@ -127,6 +128,9 @@ class PowerVR: # { def readPvm(self): + if self.debug: + print("--- READING PVM FIL ---") + bytes = self.file.read(4) p = struct.unpack('I', bytes) pvmh_len = p[0] @@ -141,6 +145,7 @@ class PowerVR: # { bytes = self.file.read(2) p = struct.unpack('H', bytes) tex = NinjaTexture() + index = p[0] tex.setIndex(p[0]) if flags & 0x08: @@ -148,6 +153,8 @@ class PowerVR: # { name = bytes.decode() name = name.replace('\x00', '') tex.setName(name) + if self.debug: + print("[%02d] %s" % (index, name)) if flags & 0x04: bytes = self.file.read(2) p = struct.unpack('H', bytes) @@ -166,7 +173,14 @@ class PowerVR: # { tex.setGlobalIndex(p[0]) self.tex_list.append(tex) + print("-- HEADER END, READING BODY ---") + + tex_len = len(self.tex_list) for tex in self.tex_list: + + if self.debug: + print("PVR Reading %d of %d" % (tex.index, tex_len)) + while self.file.tell() < self.length: bytes = self.file.read(4) if bytes != b'PVRT': @@ -193,6 +207,33 @@ class PowerVR: # { self.data_format = p[1] self.width = p[3] self.height = p[4] + + format_list = [ + "", + "TWIDDLED", + "TWIDDLED_MM", + "VQ", + "VQ_MM", + "PALETTIZE4", + "PALETTIZE4_MM", + "PALETTIZE8", + "PALETTIZE8_MM", + "RECTANGLE", + "", + "STRIDE", + "", + "TWIDDLED_RECTANGLE", + "ABGR", + "ABGR_MM", + "SMALLVQ", + "SMALLVQ_MM", + "TWIDDLED_MM_ALIAS" + ] + + if self.debug: + print("Data Format: %s" % format_list[self.data_format]) + print("Width: %d" % self.width) + print("Height: %d" % self.height) self.isTwiddled = False self.isMipmap = False @@ -292,6 +333,55 @@ class PowerVR: # { self.startOfs = self.file.tell() + if self.data_format == PowerVR.TWIDDLED_RECTANGLE: + size = 0 + dir = '' + count = 0 + if self.width > self.height: + size = self.height + dir = 'h' + count = int(self.width / self.height) + else: + size = self.width + dir = 'w' + count = int(self.height / self.width) + + if self.debug: + print("Size: %d" % size) + + for n in range(count): + + if self.debug: + print("File Position: 0x%08x" % self.file.tell()) + print("Reading square %d of %d" % (n, count)) + + self.startOfs = self.file.tell() + for y in range(size): + for x in range(size): + + i = self.untwiddle(x, y) + self.file.seek(self.startOfs + (i * 2), 0) + b = self.file.read(2) + color = struct.unpack('H', b)[0] + if self.color_format == 0: + rgba = self.ARGB_1555(color) + elif self.color_format == 1: + rgba = self.RGB_565(color) + elif self.color_format == 2: + rgba = self.ARGB_4444(color) + + if self.width > self.height: + self.bitmap[y][(n*size) + x*4 + 0] = rgba[0] + self.bitmap[y][(n*size) + x*4 + 1] = rgba[1] + self.bitmap[y][(n*size) + x*4 + 2] = rgba[2] + self.bitmap[y][(n*size) + x*4 + 3] = rgba[3] + else: + self.bitmap[y + (n*size)][x*4 + 0] = rgba[0] + self.bitmap[y + (n*size)][x*4 + 1] = rgba[1] + self.bitmap[y + (n*size)][x*4 + 2] = rgba[2] + self.bitmap[y + (n*size)][x*4 + 3] = rgba[3] + return self.bitmap + if self.isTwiddled: for y in range(self.height): for x in range(self.width): diff --git a/__init__.py b/__init__.py index 4367f3b..9024f66 100644 --- a/__init__.py +++ b/__init__.py @@ -29,6 +29,7 @@ from NinjaModel import NinjaModel ## MODELS (MISC) ## ######################################################## +""" model_file = 'MISC/BUTTON01.NJ' texture_file = 'MISC/BUTTON01.PVR' nj = NinjaModel(model_file, texture_file) @@ -90,11 +91,42 @@ model_file = 'MISC/LEVEL02.NJ' nj = NinjaModel(model_file) nj.parse() nj.export() +""" ######################################################## ## MODELS (OBJ) ## ######################################################## +model_file = 'OBJ/COCK_GPOT.NJ' +texture_file = 'OBJ/COCK_GPOT.PVM' +nj = NinjaModel(model_file, texture_file) +nj.parse() +nj.export() + +model_file = 'OBJ/COCK_LPOT.NJ' +texture_file = 'OBJ/COCK_LPOT.PVM' +nj = NinjaModel(model_file, texture_file) +nj.parse() +nj.export() + +model_file = 'OBJ/COCK_MPOT.NJ' +texture_file = 'OBJ/COCK_MPOT.PVM' +nj = NinjaModel(model_file, texture_file) +nj.parse() +nj.export() + +model_file = 'OBJ/COCK.NJ' +texture_file = 'OBJ/COCK.PVM' +nj = NinjaModel(model_file, texture_file) +nj.parse() +nj.export() + +model_file = 'OBJ/EVIL.NJ' +texture_file = 'OBJ/EVIL.PVM' +nj = NinjaModel(model_file, texture_file) +nj.parse() +nj.export() + model_file = 'OBJ/IKAL.NJ' texture_file = 'OBJ/IKAL.PVM' nj = NinjaModel(model_file, texture_file)