Offtopic: Into Commodore 64 (6502) coding, pixeling or music?
Xentax is looking for new members for the C64 activities!
Just drop us a message at forum@xentax.com and join the Scene Team!

Forum rules: Click here

My quickBMS scripts

Coders and would-be coders alike, this is the place to talk about programming.
AlphaTwentyThree
double-veteran
double-veteran
Posts: 984
Joined: Mon Aug 24, 2009 10:55 pm
Has thanked: 75 times
Been thanked: 626 times

Re: My quickBMS scripts

Post by AlphaTwentyThree » Mon Nov 07, 2011 7:26 pm

merge_mono_xadp.bms
Merges two mono Xbox ADPCM files of the same length to one stereo file. Encountered this when splitting and re-merging multichannel Xbox ADPCM files in "Disney's Cars 2: The Video Game". Each multichannel stream contains eight channels and has interleave 0x2. So deinterleaving will result in 8 mono files. As the streams actually consist of four layers, I needed to join two channels each layer. This is the script I used.
Note 1: Each file already needs to have an Xbox ADPCM header and the extension ".xadp" for the script to work
Note 2: The script will take very long to run, so don't wonder. :-\
Note 3: Resulting files may be decoded with toWAV or renamed to *.wav and played in vgmstream (I found out that toWAV decodes the stream with higher quality - don't know why)
Note 4: The PC and PS3 version of Driver: San Francisco uses an Xbox ADPCM variant that hides behind a 0x02 code identifier (a quick look at the character distribution reveals the true codec ;) ). The files are 0x24-byte-interleaved mono Xbox ADPCM files and need to be transformed to xadp. So they just need deinterleaving, adding headers and joining the channels with the below script. :)

Code: Select all

get NAME basename
string NAME -= 1
set NAME1 NAME
string NAME1 += "L.xadp"
set NAME2 NAME
string NAME2 += "R.xadp"
open FDSE NAME1 0
open FDSE NAME2 1
idstring "RIFF" 0
idstring "RIFF" 1
callfunction compare 1
goto 0x18 0
get FREQ long 0
get FSIZE asize 0
set OFFSET 0x30
do
	append
	log MEMORY_FILE OFFSET 0x4 0
	log MEMORY_FILE OFFSET 0x4 1
	append
	math OFFSET += 0x4
while OFFSET < FSIZE
get SIZE asize MEMORY_FILE
set CH 2
callfunction XADP 1
string NAME += ".xadp"
get SIZE asize MEMORY_FILE2
log NAME 0 SIZE MEMORY_FILE2

startfunction compare
	get SIZE1 asize 0
	get SIZE2 asize 1
	if SIZE1 != SIZE2
		print "ERROR: sizes are different!"
		cleanexit
	endif
	goto 0x14 0
	get CODE1 short 0
	goto 0x14 1
	get CODE2 short 1
	if CODE1 != CODE2
		print "ERROR: different codecs!"
		cleanexit
	endif
endfunction

startfunction XADP
	set MEMORY_FILE2 binary "\x52\x49\x46\x46\x18\x51\xa3\x0\x57\x41\x56\x45\x66\x6d\x74\x20\x14\x0\x0\x0\x69\x0\x2\x0\x44\xac\x0\x0\xcc\xc1\x0\x0\x48\x0\x4\x0\x2\x0\x40\x0\x64\x61\x74\x61\xf0\x50\xa3\x0"
	set RIFFSIZE SIZE # streamsize
	math RIFFSIZE += 0x28
	putVarChr MEMORY_FILE2 0x04 RIFFSIZE long
	putVarChr MEMORY_FILE2 0x16 CH byte
	putVarChr MEMORY_FILE2 0x18 FREQ long
	set VAR1 0x3073
	math VAR1 *= CH
	if FREQ == 48000
		math VAR1 *= 44100
	else
		math VAR1 *= FREQ
	endif
	math VAR1 /= 22050
	putVarChr MEMORY_FILE2 0x1c VAR1 long	
	set VAR2 0x24
	math VAR2 *= CH
	putVarChr MEMORY_FILE2 0x20 VAR2 short
	putVarChr MEMORY_FILE2 0x2c SIZE long
	get SIZE asize MEMORY_FILE
	append
	log MEMORY_FILE2 0 SIZE MEMORY_FILE
	append
endfunction
P.S.: To join multiple mono streams, use this batch file:

Code: Select all

for %%i in (*L.xadp) do quickbms merge_mono_xadp.bms "%%i" "%CD%"
Last edited by AlphaTwentyThree on Thu Nov 10, 2011 10:17 am, edited 1 time in total.
If you like what you see, why not click the little Thank You button? ;) It will definitely motivate me! :)
And here's Mr.Mouse's Facebook link: http://www.facebook.com/permalink.php?s ... 8469022795 - thanks ;)

AlphaTwentyThree
double-veteran
double-veteran
Posts: 984
Joined: Mon Aug 24, 2009 10:55 pm
Has thanked: 75 times
Been thanked: 626 times

Re: My quickBMS scripts

Post by AlphaTwentyThree » Mon Nov 07, 2011 7:30 pm

merge_VAG_to_SS2.bms
Simple vag to ss2 merger (mono to stereo). Source files need to have the format "[name]L.vag" / "[name]R.vag" for this script to work. Resulting file will be named "[name].ss2".
Run the resulting files through the re-interleave script to play correctly and cut start and end silence.

Code: Select all

get NAME basename
get EXT extension
string NAME -= 1
set NAME1 NAME
string NAME1 += "L."
string NAME1 += EXT
set NAME2 NAME
string NAME2 += "R."
string NAME2 += EXT
open FDSE NAME1 0
open FDSE NAME2 1
set HEADER 0x40
callfunction validity_test 1
set FREQ FREQ1
reverseLong FREQ
get NAME basename
string NAME -= 1
string NAME += ".ss2"
callfunction merge 1

startfunction validity_test
	get SIZE1 asize 0
	get SIZE2 asize 1
	math SIZE1 -= HEADER
	math SIZE2 -= HEADER
	if SIZE1 != SIZE2
		print "ERROR: File sizes don't match!"
		cleanexit
	endif
	goto 0x10 0
	get FREQ1 long 0
	goto 0x10 1
	get FREQ2 long 1
	if FREQ1 != FREQ2
		print "ERROR: frequencies don't match!"
		cleanexit
	endif
endfunction

startfunction merge
	set MEMORY_FILE binary "\x53\x53\x68\x64\x18\x00\x00\x00\x10\x00\x00\x00\xb0\x36\x00\x00\x02\x00\x00\x00\xc0\x2f\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x53\x53\x62\x64\x00\xe8\x11\x00"
	get SIZE asize 0
	math SIZE -= HEADER
	append
	log MEMORY_FILE HEADER SIZE 0 # append left channel
	log MEMORY_FILE HEADER SIZE 1 # append left channel
	append
	set INTERLEAVE SIZE
	putVarChr MEMORY_FILE 0xc FREQ long # frequency
	putVarChr MEMORY_FILE 0x10 2 byte # channels
	putVarChr MEMORY_FILE 0x14 SIZE long # interleave (= file size of mono file)
	get SIZE asize MEMORY_FILE
	putVarChr MEMORY_FILE 0x24 SIZE long # stream size
	log NAME 0 SIZE MEMORY_FILE
endfunction
If you like what you see, why not click the little Thank You button? ;) It will definitely motivate me! :)
And here's Mr.Mouse's Facebook link: http://www.facebook.com/permalink.php?s ... 8469022795 - thanks ;)

TEOL
ultra-n00b
Posts: 6
Joined: Thu Jan 27, 2011 7:22 pm

Re: My quickBMS scripts

Post by TEOL » Tue Nov 29, 2011 1:34 pm

Hi there. It's me again from last year. This time I'm after the plugin to detect what the extension is for any Wii ADPCM file so I can put the .whatever onto the end of the file to play it in Winamp VGM Stream.

A Wii ADPCM to Normal ADPCM converter script would be equally as helpful as an extension detection script as long as it keeps the quality of the Wii ADPCM original that's fine with me.

Here is a Wii ADPCM from the game we are trying to get the music from this year so you can make either of the scripts to help us out.

http://www.multiupload.com/28JP88K2C0

AlphaTwentyThree
double-veteran
double-veteran
Posts: 984
Joined: Mon Aug 24, 2009 10:55 pm
Has thanked: 75 times
Been thanked: 626 times

Re: My quickBMS scripts

Post by AlphaTwentyThree » Mon Dec 05, 2011 5:13 pm

TEOL wrote:Hi there. It's me again from last year. This time I'm after the plugin to detect what the extension is for any Wii ADPCM file so I can put the .whatever onto the end of the file to play it in Winamp VGM Stream.

A Wii ADPCM to Normal ADPCM converter script would be equally as helpful as an extension detection script as long as it keeps the quality of the Wii ADPCM original that's fine with me.

Here is a Wii ADPCM from the game we are trying to get the music from this year so you can make either of the scripts to help us out.

http://www.multiupload.com/28JP88K2C0
I'm afraid nothing of the above is possible. I haven't found a way to play Wii ADPCM files myself...
If you like what you see, why not click the little Thank You button? ;) It will definitely motivate me! :)
And here's Mr.Mouse's Facebook link: http://www.facebook.com/permalink.php?s ... 8469022795 - thanks ;)

AlphaTwentyThree
double-veteran
double-veteran
Posts: 984
Joined: Mon Aug 24, 2009 10:55 pm
Has thanked: 75 times
Been thanked: 626 times

Re: My quickBMS scripts

Post by AlphaTwentyThree » Mon Dec 05, 2011 5:15 pm

RIFF/RIFX to unparsed XMA
Converts any RIFF or RIFX file that contains XMA data to a headerless and presumably unparsed XMA file with frequency and channels included in the name. Parsing and/or adding a header is pretty easy now, especially when processing multiple files.
Edit: now also with cue marker extraction. :)

Code: Select all

# RIFF_to_uxma.bms
# transforms xma streams with RIFF or RIFX header to headerless XMA streams (*.uxma)
# output files have the format "<name>@FREQ[m/s].uxma"
# resulting files can be parsed if necessary
# a valid XMA header can be added with my header_adder_XMA.bms
# 
# cue markers are saved as <name>.cue
# they can be applied to the decoded wave files with my wave cue adder
# 
# 
# (c) 2012-04-07 by AlphaTwentyThree of XeNTaX

getDstring IDENT 4
if IDENT == "RIFF"
elif IDENT == "RIFX"
	endian big
else
	print "ERROR: No RIFF or RIFX header found!"
	cleanexit
endif
callfunction process 1

get NAME basename
string NAME += "@"
string NAME += FREQ
if CH == 1
	string NAME += "m"
elif CH == 2
	string NAME += "s"
endif
string NAME += ".uxma"
do
	findLoc OFFSET string "data" 0 ""
	goto OFFSET
	idstring "data"
	get SIZE long
while SIZE == 0 # skip marker section to find stream size
math OFFSET += 0x8
log NAME OFFSET SIZE

goto 0
findLoc MARKERS string "cue " 0 ""
if MARKERS != ""
	if MARKERS < OFFSET # in header
		goto MARKERS
		idstring "cue "
		get SIZE long
		math SIZE += 8
		append
		log MEMORY_FILE MARKERS SIZE
		append
		math MARKERS += SIZE
		goto MARKERS
		getDstring IDENT 4
		if IDENT == "LIST"
			get SIZE long
			math SIZE += 8
			append
			log MEMORY_FILE MARKERS SIZE
			append
		endif
		get SIZE asize MEMORY_FILE
		get NAME basename
		string NAME += ".cue"
		log NAME 0 SIZE MEMORY_FILE
	endif
endif

startfunction process
	goto 0x14
	get CODE short
	if CODE == 0x165
		goto 0x24
		get FREQ long
		goto 0x31
		get CH byte
	elif CODE == 0x166
		get CH short
		get FREQ long
	elif CODE == 0x104
		endian big
		goto 0x20
		get FREQ long
		goto 0x3c
		get CH byte
	elif CODE == 0x401
		endian big
		goto 0x20
		get FREQ long
		goto 0x3c
		get CH byte
	else
		print "No XMA file. Aborting..."
		cleanexit
	endif
	
endfunction
Last edited by AlphaTwentyThree on Sat Apr 07, 2012 4:46 pm, edited 3 times in total.
If you like what you see, why not click the little Thank You button? ;) It will definitely motivate me! :)
And here's Mr.Mouse's Facebook link: http://www.facebook.com/permalink.php?s ... 8469022795 - thanks ;)

AlphaTwentyThree
double-veteran
double-veteran
Posts: 984
Joined: Mon Aug 24, 2009 10:55 pm
Has thanked: 75 times
Been thanked: 626 times

Re: My quickBMS scripts

Post by AlphaTwentyThree » Fri Feb 10, 2012 12:43 am

Corrected the XMA header adder. The script stopped with an error message when no frequency was given in the file name... Works fine now with all uxma files.
Next step is to enhance the script with the new external exe execution feature (xxx) of QuickBMS:
  • automatically parse headerless xma files if the source is XMA2, automatically parse multichannel files correctly and add headers to each stereo stream. Need to include some (brute-force) blocksize detection for this.
  • enhance the RIFF_to_uxma script to something like XMA_to_XMA (input: xma or xma2 file with RIFF or RIFF header, output: decodable xma file or multiple stereo files respectively)
  • eventually an XMA scanner that automatically extracts and transforms xma streams out of an archive.
The last script will be really exciting to program because there are quite a few things to mind like the pure stream size detection via xma_parse.
Stay tuned for updates. :)
If you like what you see, why not click the little Thank You button? ;) It will definitely motivate me! :)
And here's Mr.Mouse's Facebook link: http://www.facebook.com/permalink.php?s ... 8469022795 - thanks ;)

AlphaTwentyThree
double-veteran
double-veteran
Posts: 984
Joined: Mon Aug 24, 2009 10:55 pm
Has thanked: 75 times
Been thanked: 626 times

Re: My quickBMS scripts

Post by AlphaTwentyThree » Fri Feb 10, 2012 12:52 am

Armored Core V Xbox 360 (bdt/bht)
Extracts the big archive from the new Armored Core V. Only the name crcs are given, no actual file names. There seem to be groups of files, each group has a number of files associated although the file groups have no apparent meaning after extraction. You may adjust the script for your desires like only having the file number at the end of the file name. It's stored in the FNUM variable which isn't used in the below script but as I already included it to check the file count I thought I just keep it unused if anyone needs it. :D
note: there are file types that can't be detected by their start. Those won't have any extension after the extraction.
UPDATE: externalized the type identification - use func_getTYPE.bms now!

Code: Select all

# extracts the contents of bt/bhdd archive pairs
# supported games: Armored Core V (Xbox 360)
# NOTE: make sure, both bdt and bht files have the same name before running the script!
#
# (c) 2012-03-25 by AlphaTwentyThree of XeNTaX

include "func_getTYPE.bms"
open FDDE bhd 0
open FDDE bdt 1

endian big
idstring "BHD5" 0
get ZERO long 0
get UNK long 0
get FSIZE long 0
get GROUPS long 0 # file groups?
get UNK long 0
set FNUMB 0
for i = 1 <= GROUPS
	get FILES long 0 # number of files of same group
	get INFO long 0
	savepos MYOFF 0
	goto INFO 0
	for j = 1 <= FILES
		get NAME_CRC long 0
		get SIZE long 0
		get ZERO long 0
		get OFFSET long 0
		get NAME basename 0
		callfunction constructname 1
		endian little
		callfunction getTYPE 1
		endian big
		string NAME += EXT
		log NAME OFFSET SIZE 1
	next j
	goto MYOFF 0
next i

startfunction constructname
	math FNUMB += 1
	string NAME += "_"
	string NAME += i
	string NAME += "~"
	string NAME += FNUMB
	string NAME += "_0x"
	string NAME_CRC p= "%08x" NAME_CRC
	string NAME += NAME_CRC
endfunction
Last edited by AlphaTwentyThree on Wed May 30, 2012 4:12 am, edited 2 times in total.
If you like what you see, why not click the little Thank You button? ;) It will definitely motivate me! :)
And here's Mr.Mouse's Facebook link: http://www.facebook.com/permalink.php?s ... 8469022795 - thanks ;)

AlphaTwentyThree
double-veteran
double-veteran
Posts: 984
Joined: Mon Aug 24, 2009 10:55 pm
Has thanked: 75 times
Been thanked: 626 times

Re: My quickBMS scripts

Post by AlphaTwentyThree » Fri Feb 10, 2012 1:27 am

Star Wars: The Force Unleashed PC (pcp/pcd)
Extracts the sounds from the game. Have to be post-processed with the next script.

Code: Select all

open FDDE pcd 0
open FDDE pcp 1

get UNK long 0
get UNK long 0
get FILES long 0
get NAMESTART long 0
set NAMEOFF FILES
math NAMEOFF *= 0x1c
math NAMEOFF += 0x10
math NAMEOFF += NAMESTART # only in some files
get FOLDER basename
string FOLDER += "/"
for i = 1 <= FILES
	get CRC long 0
	get OFFSET long 0
	get OFFSET2 long 0
	get SIZE long 0
	get FFFF long 0
	get UNK long 0
	get ZERO long 0
	savepos MYOFF 0
	goto NAMEOFF 0
	get NAMEL long 0
	getDstring NAME NAMEL 0
		#set NAME2 FOLDER
		#string NAME2 += NAME
		#set NAME NAME2
	savepos NAMEOFF 0
	string NAME += ".pcm"
	log NAME OFFSET SIZE 1
	goto MYOFF 0
next i

Star Wars: The Force Unleashed PC (pcm post-processing)
Extracted files are either uncompressed wave files or MS ADPCM.

Code: Select all

get CODE short
if CODE == 2
	callfunction msadpcm 1
elif CODE == 1
	callfunction pcm 1
else
	print "error: unknown codec"
endif
get SIZE asize MEMORY_FILE
get NAME basename
string NAME += ".wav"
log NAME 0 SIZE MEMORY_FILE

startfunction msadpcm
	set MEMORY_FILE binary "\x52\x49\x46\x46\x9C\xA8\x80\x00\x57\x41\x56\x45\x66\x6D\x74\x20\x32\x00\x00\xff"
	# note: byte at 0x13 has to be set to 0 later
	append
	log MEMORY_FILE 0 0x32
	append
	putVarChr MEMORY_FILE 0x46 0x61746164 long # "data"
	putVarChr MEMORY_FILE 0x4a 0xffffffff long # placeholder
	putVarChr MEMORY_FILE 0x13 0 byte
	set OFFSET 0x32
	get SIZE asize
	math SIZE -= OFFSET
	append
	log MEMORY_FILE OFFSET SIZE
	append
	putVarChr MEMORY_FILE 0x4a SIZE long # actual streamsize
	get RIFFSIZE asize MEMORY_FILE
	math RIFFSIZE -= 8
	putVarChr MEMORY_FILE 4 RIFFSIZE long
endfunction

startfunction pcm
	goto 2
	get CHANNELS short
	get FREQUENCY short
	set BITS 16
	set OFFSET 0x10
	get SIZE asize
	math SIZE -= OFFSET
	set MEMORY_FILE binary "\x52\x49\x46\x46\x00\x00\x00\x00\x57\x41\x56\x45\x66\x6d\x74\x20\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x64\x61\x74\x61\xff\xff\xff\xff"
	append
	log MEMORY_FILE OFFSET SIZE
	append

	set RIFFSIZE SIZE
	math RIFFSIZE += 36
	set BLOCKALIGN BITS
	set AVGBYTES FREQUENCY
	math BLOCKALIGN /= 8
	math BLOCKALIGN *= CHANNELS
	math AVGBYTES *= BLOCKALIGN

	putvarchr MEMORY_FILE 4 RIFFSIZE long
	putvarchr MEMORY_FILE 20 1 short          # wFormatTag: Microsoft PCM Format (0x0001)
	putvarchr MEMORY_FILE 22 CHANNELS short   # wChannels
	putvarchr MEMORY_FILE 24 FREQUENCY long   # dwSamplesPerSec
	putvarchr MEMORY_FILE 28 AVGBYTES long    # dwAvgBytesPerSec
	putvarchr MEMORY_FILE 32 BLOCKALIGN short # wBlockAlign
	putvarchr MEMORY_FILE 34 BITS short       # wBitsPerSample
	putvarchr MEMORY_FILE 40 SIZE long
endfunction
Part of the wave header function is (c)Luigi Auriemma - thanks for that buddy ;)
If you like what you see, why not click the little Thank You button? ;) It will definitely motivate me! :)
And here's Mr.Mouse's Facebook link: http://www.facebook.com/permalink.php?s ... 8469022795 - thanks ;)

AlphaTwentyThree
double-veteran
double-veteran
Posts: 984
Joined: Mon Aug 24, 2009 10:55 pm
Has thanked: 75 times
Been thanked: 626 times

Re: My quickBMS scripts

Post by AlphaTwentyThree » Sat Feb 11, 2012 2:14 am

Just updated the RIFF/RIFX to unparsed xma script by another file type. =)
If you like what you see, why not click the little Thank You button? ;) It will definitely motivate me! :)
And here's Mr.Mouse's Facebook link: http://www.facebook.com/permalink.php?s ... 8469022795 - thanks ;)

AlphaTwentyThree
double-veteran
double-veteran
Posts: 984
Joined: Mon Aug 24, 2009 10:55 pm
Has thanked: 75 times
Been thanked: 626 times

Re: My quickBMS scripts

Post by AlphaTwentyThree » Wed Feb 15, 2012 2:29 am

Updated the str audio extractor for Playstation movies. Also works for multistream videos now. :)
If you like what you see, why not click the little Thank You button? ;) It will definitely motivate me! :)
And here's Mr.Mouse's Facebook link: http://www.facebook.com/permalink.php?s ... 8469022795 - thanks ;)

AlphaTwentyThree
double-veteran
double-veteran
Posts: 984
Joined: Mon Aug 24, 2009 10:55 pm
Has thanked: 75 times
Been thanked: 626 times

Re: My quickBMS scripts

Post by AlphaTwentyThree » Wed Feb 22, 2012 10:21 pm

Nintedo DS SDAT extractor
Finally finished this one. Why? BECAUSE ALL PREVIOUS EXTACTORS WERE ERRORNOUS!!! One extracted only *.strm files, one extracted no *.strm files - damn! Wrote almost three days at this; strange format.

Code: Select all

# extracts the contents of Nintendo DS *.sdat sound containers
#(c) 2012-03-18 by AlphaTwentyThree of XeNTaX

idstring "SDAT"
get UNK short
get UNK short
get FILESIZE long
get INFO_AREA short # header length
get UNK short

# write sections to memory files 
get pSYMBOL long # SYMB offset
get sSYMBOL long # SYMB size
	putVarChr MEMORY_FILE sSYMBOL 0
	log MEMORY_FILE 0 0
	log MEMORY_FILE pSYMBOL sSYMBOL
get pINFO long   # INFO offset
get sINFO long   # INFO size
	putVarChr MEMORY_FILE2 sINFO 0
	log MEMORY_FILE2 0 0
	log MEMORY_FILE2 pINFO sINFO
get pFAT long    # FAT offset
get sFAT long    # FAT size
	putVarChr MEMORY_FILE3 sFAT 0
	log MEMORY_FILE3 0 0
	log MEMORY_FILE3 pFAT sFAT
get pFILE long   # FILE offset
get sFILE long   # FILE size
	putVarChr MEMORY_FILE4 sFILE 0
	log MEMORY_FILE4 0 0
	log MEMORY_FILE4 pFILE sFILE

PutArray 0 0 "/Seq/"
PutArray 0 1 "/SeqArc/"
PutArray 0 2 "/Bank/"
PutArray 0 3 "/WaveArc/"
PutArray 0 4 "/Player/"
PutArray 0 5 "/Group/"
PutArray 0 6 "/PlayerSTRM/"
PutArray 0 7 "/STRM/"

PutArray 1 0 ".sseq"
PutArray 1 1 ".ssar"
PutArray 1 2 ".sbnk"
PutArray 1 3 ".swar"
PutArray 1 4 ".ply"
PutArray 1 5 "" # different extensions
PutArray 1 6 ".strm"
PutArray 1 7 ".strm"

set FIRSTNAME 0
for i = 0 <= 7
	set INIPOS i # initial position without area bias
	math INIPOS *= 4
	math INIPOS += 8 # skip IDENT and AREA_SIZE
	
	# name information
	goto INIPOS MEMORY_FILE
	get NPOS long MEMORY_FILE
	goto NPOS MEMORY_FILE
	get FILES long MEMORY_FILE
	savepos NAME_INFO MEMORY_FILE
	
	# position of size/offset information in FAT area
	goto INIPOS MEMORY_FILE2
	get IPOS long MEMORY_FILE2
	goto IPOS MEMORY_FILE2
	get FILES2 long MEMORY_FILE2 # not needed (duplicate value)
	savepos INFO_POS MEMORY_FILE2
	
	getArray FOLDER 0 i
	getArray EXT 1 i
	get FPATH basename
	string FPATH += FOLDER
	
	# MEMORY_FILE 	: 	SYMB (names)
	# MEMORY_FILE2 	: 	INFO (pointer to offset/size)
	# MEMORY_FILE3 	: 	FAT (offset/sizes)
	# MEMORY_FILE4 	: 	FILE (binary data)
	for j = 1 <= FILES
		# get name
		goto NAME_INFO MEMORY_FILE
		get NAMEPOS long MEMORY_FILE
		savepos NAME_INFO MEMORY_FILE
		if FIRSTNAME == 0
			set FIRSTNAME NAMEPOS
		endif
		if NAMEPOS < FIRSTNAME
			do
				get NAMEPOS long MEMORY_FILE
				savepos NAME_INFO
			while NAMEPOS < FIRSTNAME
		endif
		goto NAMEPOS MEMORY_FILE
		get NAME string MEMORY_FILE
		set FNAME FPATH
		string FNAME += NAME
		string FNAME += EXT
		
		# get file ID
		goto INFO_POS MEMORY_FILE2 
		get ID_INFO long MEMORY_FILE2
		savepos INFO_POS MEMORY_FILE2
		goto ID_INFO MEMORY_FILE2
		if i == 4 # do nothing (?)
		elif i == 6 # do nothing (?)
		else
			get FILE_ID short MEMORY_FILE2
			# get offset/size
			set OFFPOS FILE_ID
			math OFFPOS *= 0x10
			math OFFPOS += 0xc # skip header
			goto OFFPOS MEMORY_FILE3
			get OFFSET long MEMORY_FILE3
			math OFFSET -= pFILE # offset it total offset in sdat
			get SIZE long MEMORY_FILE3
			if i == 5
				callfunction getEXT 1
			endif
			log FNAME OFFSET SIZE MEMORY_FILE4
		endif
	next j
next i

startfunction getEXT
	goto OFFSET MEMORY_FILE4
	getDstring IDENT 4 MEMORY_FILE4
	if IDENT == "SWAR"
		string FNAME += ".swar"
	elif IDENT == "SBNK"
		string FNAME += ".sbnk"
	elif IDENT == "SSAR"
		string FNAME += ".ssar"
	elif IDENT == "STRM"
		string FNAME += ".strm"
	endif
endfunctioni
Last edited by AlphaTwentyThree on Sun Mar 18, 2012 7:26 pm, edited 4 times in total.
If you like what you see, why not click the little Thank You button? ;) It will definitely motivate me! :)
And here's Mr.Mouse's Facebook link: http://www.facebook.com/permalink.php?s ... 8469022795 - thanks ;)

AlphaTwentyThree
double-veteran
double-veteran
Posts: 984
Joined: Mon Aug 24, 2009 10:55 pm
Has thanked: 75 times
Been thanked: 626 times

Re: My quickBMS scripts

Post by AlphaTwentyThree » Wed Feb 22, 2012 10:43 pm

Function: convert number to hex string
As the new version of QuickBMS supports external functions (YAY!!!), here's an example. Save the below code as num2hex.bmsf. Accessing the function works by adding the line

Code: Select all

include "num2hex.bmsf"
to the start of your script.
The number you want to convert has to be named TOHEX. When you call the function (callfunction num2hex 1), the resulting hex string is saved in the same variable.

Code: Select all

startfunction num2hex
	strlen LENGTH TOHEX
	if LENGTH == 8
		string TOHEX p= "0x%08x" TOHEX
	elif LENGTH == 7
		string TOHEX p= "0x%07x" TOHEX
	elif LENGTH == 6
		string TOHEX p= "0x%06x" TOHEX
	elif LENGTH == 5
		string TOHEX p= "0x%05x" TOHEX
	elif LENGTH == 4
		string TOHEX p= "0x%04x" TOHEX
	elif LENGTH == 3
		string TOHEX p= "0x%03x" TOHEX
	elif LENGTH == 2
		string TOHEX p= "0x%02x" TOHEX
	elif LENGTH == 1
		string TOHEX p= "0x%01x" TOHEX
	endif
endfunction
If you like what you see, why not click the little Thank You button? ;) It will definitely motivate me! :)
And here's Mr.Mouse's Facebook link: http://www.facebook.com/permalink.php?s ... 8469022795 - thanks ;)

AlphaTwentyThree
double-veteran
double-veteran
Posts: 984
Joined: Mon Aug 24, 2009 10:55 pm
Has thanked: 75 times
Been thanked: 626 times

Re: My quickBMS scripts

Post by AlphaTwentyThree » Wed Feb 22, 2012 11:47 pm

Nintendo DS SWAR extractor
Extracts *.swav files out of swar archives (WaveArc). Playable with vgmstream. I know that VGMTrans can export swar files to dls instrument collections but there are sometimes other *.swar files that either aren't used in the banks or are completely stand-alone e.g. when there's no bank/seq area in the sdat. Experienced in GemQuest: 4 Elements and 7th Dragon so far but there are surely many others.

Code: Select all

# Nintendo DS swar extractor
# (c) 2012-02-22 by AlphaTwentyThree of XeNTaX

idstring "SWAR"
get MAGIC long # 0xfffe0001
get SIZE long # file size
get HEADER short # SWAR size
get BLOCKS short # always 1
idstring "DATA"
get DSIZE long # size of DATA area
savepos MYOFF
math MYOFF += 0x20
goto MYOFF
get FILES long
for i = 1 <= FILES
	get OFFSET long
	if i != FILES
		savepos MYOFF
		get SIZE long
		goto MYOFF
	else
		get SIZE asize
	endif
	math SIZE -= OFFSET
	get NAME basename
	string NAME += "_"
	string NAME += i
	string NAME += ".swav"
	callfunction SWAV 1
next i


startfunction SWAV
	set MEMORY_FILE binary "\x53\x57\x41\x56\xFF\xFE\x00\x01\xA8\x61\x0F\x00\x10\x00\x01\x00\x44\x41\x54\x41\x98\x61\x0F\x00"
	append
	log MEMORY_FILE OFFSET SIZE
	append
	math SIZE += 0x8
	putVarChr MEMORY_FILE 0x14 SIZE long
	get SIZE asize MEMORY_FILE
	putVarChr MEMORY_FILE 0x8 SIZE long
	log NAME 0 SIZE MEMORY_FILE
endfunction
Last edited by AlphaTwentyThree on Thu Feb 23, 2012 7:52 am, edited 1 time in total.
If you like what you see, why not click the little Thank You button? ;) It will definitely motivate me! :)
And here's Mr.Mouse's Facebook link: http://www.facebook.com/permalink.php?s ... 8469022795 - thanks ;)

AlphaTwentyThree
double-veteran
double-veteran
Posts: 984
Joined: Mon Aug 24, 2009 10:55 pm
Has thanked: 75 times
Been thanked: 626 times

Re: My quickBMS scripts

Post by AlphaTwentyThree » Thu Feb 23, 2012 12:43 am

IMPORTANT UPDATE:
Just had to update my sdat extractor because there seem to be sdat files where the area with the file name pointers contains some unused information and the script searched for the name at the wrong offset. Fixed that problem with a little nasty work-around. Seems to work. ;)
If you like what you see, why not click the little Thank You button? ;) It will definitely motivate me! :)
And here's Mr.Mouse's Facebook link: http://www.facebook.com/permalink.php?s ... 8469022795 - thanks ;)

AlphaTwentyThree
double-veteran
double-veteran
Posts: 984
Joined: Mon Aug 24, 2009 10:55 pm
Has thanked: 75 times
Been thanked: 626 times

Re: My quickBMS scripts

Post by AlphaTwentyThree » Thu Feb 23, 2012 7:14 am

Nintendo DS bank.bin extractor
This extractor is for those NDS roms that only contain that one bank.bin file. There may be other formats to adjust the extension for and I'll update the script as soon as I find another game with this format.
Needs my func_getTYPE.bms to get file types.

Code: Select all

# extract Nintendo DS *.bin files
# this is for NDS roms that only contain one single bin file
# supported games (more to come):
# - 1 vs 100
# - A Prendre ou A Laisser (FR)
# - Affari Tuoi (IT)
# - Dolphin Island: Underwater Adventures
# - Imagine: Teacher: Class Trip
# - Totally Spies! 3 - Sectet Agents
# 
# (c) 2012-03-19 by AlphaTwentyThree of XeNTaX

include "func_getTYPE.bms"
get ZERO long
get DATASTART long
set FILES DATASTART
math FILES -= 8
math FILES /= 8
for i = 1 <= FILES
	get OFFSET long
	get SIZE long
	get NAME basename
	string NAME += "_"
	string NAME += i
	callfunction getTYPE 1
	string NAME += EXT
	log NAME OFFSET SIZE
next i
Here's a guide how to get the music from these games:
I suppose you know how to extract *.nds roms, otherwise you wouldn't be here. ;)
1. Extract the bin file and locate the *.xm tracker files
2. Open all xm files with a hex editor
3. Scroll to the end of each xm file to locate the sample list. The samples are named "XMSMP_000.snd" up to a number you need to locate. They _should_ be sequentially named but don't be too sure about this. Look, how many samples occur in the xm files. Note that they start at zero, so if the highest sample is "XMSMP_030.snd", there are 31 samples in total.
4. Make a new folder and copy the above number of files from the end to that folder. These should only have the extensions *.dat or *.ez
5. You may need to decompress the *.ez files (as soon as somebody cracks the compression).
6. To keep track of the samples, rename them to the names needed (XMSMP_####.raw).
7. All the files are normally uncompressed PCM files. The frequency isn't given, so you should try some possibilities. So far I only encountered 11025 Hz mono 16bit, but there may be games which use others. Import the samples to any audio editor with the given specs. Save them as wav.
7. Open each xm file in Modplug Tracker and add as many samples as given in the sample list (check again via hex if you forgot). Import the wav samples from the xm sample list. IMPORTANT: keep the same order as in the list!
8. Save the file with Ctrl+S. Modplug Tracker will create an ImpulseTracker (*.it) file from the xm.
Last edited by AlphaTwentyThree on Mon Mar 19, 2012 3:04 am, edited 3 times in total.
If you like what you see, why not click the little Thank You button? ;) It will definitely motivate me! :)
And here's Mr.Mouse's Facebook link: http://www.facebook.com/permalink.php?s ... 8469022795 - thanks ;)

Post Reply