Page 1 of 1

BlazBlue Cross Tag Battle PC Noesis Script Help

Posted: Sat Mar 07, 2020 6:00 am
by reh
I am adventuring to understand a little about creating a script for Noesis and seeing some topics as a basis, this is where i got, the script reads the file, but the face count is not correct for the body.
0000_brg.MUA.png

Re: BlazBlue Cross Tag Battle PC Noesis Script Help

Posted: Sat Mar 07, 2020 6:03 am
by reh
This is the code:
fmt_BlazBlueCrossTagBattle_PC.py

Code: Select all

from inc_noesis import *
import noesis
import rapi

def registerNoesisTypes():
	handle = noesis.register("BlazBlue Cross Tag Battle PC",".MUA")
	noesis.setHandlerTypeCheck(handle, noepyCheckType)
	noesis.setHandlerLoadModel(handle, noepyLoadModel)
	return 1
	
NOEPY_HEADER = "MUA"

def noepyCheckType(data):
   bs = NoeBitStream(data)
   if len(data) < 3:
      return 0
   if bs.readBytes(3).decode("ASCII") != NOEPY_HEADER:
      return 0
   return 1  

def noepyLoadModel(data, mdlList):
	ctx = rapi.rpgCreateContext()
	bs = NoeBitStream(data)
	bs.seek(0x94, NOESEEK_ABS)
	FCount = bs.readUInt()
	bs.seek(0x8c, NOESEEK_ABS)
	VCount = bs.readUInt()
	bs.seek(0x90, NOESEEK_ABS)
	FAddress = bs.readUInt()
	bs.seek(0x88, NOESEEK_ABS)
	VAddress = bs.readUInt()
	VBSize = int(80)
	bs.seek(VAddress, NOESEEK_ABS)
	VBuff = bs.readBytes(VCount * VBSize)
	rapi.rpgBindPositionBufferOfs(VBuff, noesis.RPGEODATA_FLOAT, VBSize, 0)
	rapi.rpgBindUV1BufferOfs(VBuff, noesis.RPGEODATA_FLOAT, VBSize,36)
	bs.seek(FAddress, NOESEEK_ABS)
	FBuff = bs.readBytes(FCount * 2)
	rapi.rpgCommitTriangles(FBuff, noesis.RPGEODATA_USHORT, FCount, noesis.RPGEO_TRIANGLE_STRIP, 1)
	mdl = rapi.rpgConstructModel()
	mdlList.append(mdl)
	
	rapi.rpgClearBufferBinds()
	return 1
Sample file:
0000_brg.zip

Re: BlazBlue Cross Tag Battle PC Noesis Script Help

Posted: Sat Mar 07, 2020 8:29 am
by shakotay2
reh wrote: Sat Mar 07, 2020 6:00 amthis is where i got, the script reads the file, but the face count is not correct for the body.
I wouldn't say so, 4096 looks like the overall faceindex count.
Guess you need to find/use all the counts (colored: 2nd submesh):
.
MUA-counts.png
Maybe check in other MUAs whether the pattern 01000000 01000000 is some kind of marker to find the vertex counts.

And, well, just in case, here's the heavy stuff (needs to be modified/expanded to find the 2nd occurence):

Code: Select all

	addr=bs.tell()
	fileBuff = bs.data[addr:bs.dataSize]
	bs.seek(addr+fileBuff.find(b'\x01\x00\x00\x00\x01\x00\x00\x00'))
	offset= bs.tell()
	print("01000000 01000000:", hex(offset))

Re: BlazBlue Cross Tag Battle PC Noesis Script Help

Posted: Mon Mar 09, 2020 4:02 am
by reh
shakotay2 wrote: Sat Mar 07, 2020 8:29 am
Guess you need to find/use all the counts (colored: 2nd submesh):
How do I use more than one count?
Would I use more variables to store them? (Ex: Vcont1, Vcont2, ...).
shakotay2 wrote: Sat Mar 07, 2020 8:29 am
Maybe check in other MUAs whether the pattern 01000000 01000000 is some kind of marker to find the vertex counts.
Apparently, yes.
shakotay2 wrote: Sat Mar 07, 2020 8:29 am And, well, just in case, here's the heavy stuff (needs to be modified/expanded to find the 2nd occurence):

Code: Select all

	addr=bs.tell()
	fileBuff = bs.data[addr:bs.dataSize]
	bs.seek(addr+fileBuff.find(b'\x01\x00\x00\x00\x01\x00\x00\x00'))
	offset= bs.tell()
	print("01000000 01000000:", hex(offset))
As I understand it, this snippet points to the address before the vertex count (0x8B), but I don't understand exactly what I should do with it.

Excuse me if I seem too noob in my doubts.

Re: BlazBlue Cross Tag Battle PC Noesis Script Help

Posted: Mon Mar 09, 2020 8:36 am
by shakotay2
reh wrote: Mon Mar 09, 2020 4:02 amAs I understand it, this snippet points to the address before the vertex count (0x8B), but I don't understand exactly what I should do with it.
What? It's for finding the counts which you need to use in the script then (more code to write, of course).

And as I wrote you need to find the second occurence of 01000000 01000000 in that file (dunno whether it's always the 2nd one).
Then seek 8 bytes (bs.seek(0x08, NOESEEK_REL)), read the count(s), use the count(s) (face index counts need additional code, btw).

In the end you can get the two submeshes (see
reh wrote: Sat Mar 07, 2020 6:00 am
) in a loop.

Re: BlazBlue Cross Tag Battle PC Noesis Script Help

Posted: Fri Mar 13, 2020 10:04 pm
by shakotay2
How is it going? :)

Updated your script a little bit. (Assuming the counts to follow after the 2nd 0100000001000000.)
As always python was giving me some headache so I made a poor patch (without a loop as it should have been) :D :
.
0000_brg-MUA.png
Also didn't care for the mesh count - just used 2. Script tested with 0000_brg.MUA only!

Code: Select all

from inc_noesis import *
import noesis
import rapi

def registerNoesisTypes():
	handle = noesis.register("BlazBlue Cross Tag Battle PC",".MUA")
	noesis.setHandlerTypeCheck(handle, noepyCheckType)
	noesis.setHandlerLoadModel(handle, noepyLoadModel)
	return 1
	
NOEPY_HEADER = "MUA"

def noepyCheckType(data):
   bs = NoeBitStream(data)
   if len(data) < 3:
      return 0
   if bs.readBytes(3).decode("ASCII") != NOEPY_HEADER:
      return 0
   return 1  

def noepyLoadModel(data, mdlList):
	ctx = rapi.rpgCreateContext()
	bs = NoeBitStream(data)
	addr=bs.tell()
	fileBuff = bs.data[addr:bs.dataSize]
	addr1= fileBuff.find(b'\x01\x00\x00\x00\x01\x00\x00\x00')
	addr += addr1
	bs.seek(addr)
	offset= bs.tell()
	#print("01000000:", hex(offset))
	addr += 8 #skip found bytes
	fileBuff = bs.data[addr:bs.dataSize]
	addr2= fileBuff.find(b'\x01\x00\x00\x00\x01\x00\x00\x00')
	addr += addr2 + 8
	bs.seek(addr)

	# submesh 2 value comes first
	vCnt2 = bs.readUInt()
	vCnt1 = bs.readUInt()
	bs.seek(12*16+12, NOESEEK_REL)# this offset maybe different for other modell files
	fCnt2 = bs.readUInt()
	fCnt1 = bs.readUInt()
	print("vCnt1,2  fCnt1,2", vCnt1,vCnt2,fCnt1,fCnt2)
	# using the addresses here only, ignore overall counts
	bs.seek(0x94, NOESEEK_ABS)
	FCount = bs.readUInt()
	bs.seek(0x8c, NOESEEK_ABS)
	VCount = bs.readUInt()
	bs.seek(0x90, NOESEEK_ABS)
	FAddress = bs.readUInt()
	bs.seek(0x88, NOESEEK_ABS)
	VAddress = bs.readUInt()
	VBSize = int(80)
	bs.seek(VAddress, NOESEEK_ABS)
	print("(FVFsize: {}) {} {} f {} v {}".format(VBSize, FCount, VCount, hex(FAddress), hex(VAddress)))
	VBuff = bs.readBytes(vCnt1 * VBSize)
	rapi.rpgBindPositionBufferOfs(VBuff, noesis.RPGEODATA_FLOAT, VBSize, 0)
	rapi.rpgBindUV1BufferOfs(VBuff, noesis.RPGEODATA_FLOAT, VBSize,36)
	bs.seek(FAddress, NOESEEK_ABS)
	FBuff = bs.readBytes(fCnt1 * 2)
	rapi.rpgCommitTriangles(FBuff, noesis.RPGEODATA_USHORT, fCnt1, noesis.RPGEO_TRIANGLE_STRIP, 1)
	# handling submesh 2
	VAddress += vCnt1*VBSize
	bs.seek(VAddress, NOESEEK_ABS)
	VBuff = bs.readBytes(vCnt2 * VBSize)
	rapi.rpgBindPositionBufferOfs(VBuff, noesis.RPGEODATA_FLOAT, VBSize, 0)
	rapi.rpgBindUV1BufferOfs(VBuff, noesis.RPGEODATA_FLOAT, VBSize,36)
	FAddress += fCnt1*2
	bs.seek(FAddress, NOESEEK_ABS)
	FBuff = bs.readBytes(fCnt2 * 2)
	rapi.rpgCommitTriangles(FBuff, noesis.RPGEODATA_USHORT, fCnt2, noesis.RPGEO_TRIANGLE_STRIP, 1)

	mdl = rapi.rpgConstructModel()
	mdlList.append(mdl)
	
	rapi.rpgClearBufferBinds()
	return 1
	

Re: BlazBlue Cross Tag Battle PC Noesis Script Help

Posted: Sat Mar 14, 2020 7:48 am
by reh
I've been reading some topics about python repetition structure to better understand what I should do with the loop, thank you very much for taking the time to tinker with the code and for having spent some headaches. :D
The script works with the characters found in lobby3d, but it doesn't work with stages and most effects, I have to see why that is.
However, my initial intention was to acquire knowledge. :read:

PS: The script also works with the nintendo switch version and probably works with the PS4 version.
To get the texture, use the Switch-Toolbox .