My first quickBMS script

Programming related discussions related to game research
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: My first quickBMS script

Post by aluigi »

Unfortunately I can't help with these things.
Simply checking your script and the archive, doing tests and so on will take a so big amount of time that it's more easy to write a script on my self from scratch.
Sorry but time and desire are really very limited.
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: My first quickBMS script

Post by AnonBaiter »

Well I wish I could've taken advantage of that. Not that it is worth a shot anyway.
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: My first quickBMS script

Post by AnonBaiter »

Aha!
Turns out the INFO_OFF variable was referenced all along!

Code: Select all

. 0000000000000000 get     BF_SIZE    0x000000008171f000 -2
. 0000000000000000 get     EXT        "bf" -1002
. 0000000000000000 idstr              "BIG" 4
    42 49 47 00                                       BIG.
. 0000000000000004 get     DUMMY1     0x0000000000000022 4
. 0000000000000008 get     DUMMY2     0x00000000000022dc 4
. 000000000000000c get     DUMMY3     0x0000000000002b0f 4
. 0000000000000010 get     DUMMY4     0x0000000000000000 8
. 0000000000000018 get     DUMMY5     0xffffffffffffffff 8
. 0000000000000020 get     INFO_SIZE  0x0000000000002b9e 4
. 0000000000000024 get     DUMMY6     0x0000000000000001 4
. 0000000000000028 get     DUMMY7     0x0000000071003ff9 4
. 000000000000002c get     FILES      0x00000000000022dc 4
. 0000000000000030 get     ENTRIES    0x0000000000002b0f 4
. 0000000000000034 get     INFO_OFF   0x0000000000000044 4
. 0000000000000038 get     DUMMY8     0x00000000ffffffff 4
. 000000000000003c get     DUMMY9     0x0000000000000000 4
. 0000000000000040 get     DUMMY10    0x0000000000002b9d 4
. 00000000 putarr  INFO_OFF   0x0000000000000044 0:0
. 00000000 putarr  NAMES_OFF  0x0000000000015d34 1:0
. 00000000 putarr  FOLDERS_OFF 0x00000000000fad0c 2:0
How did you manage to do this, you ask? I had a source code of some tool of a similar purpose, and the moment I looked at it... I then realized what I had to do.

Code: Select all

xmath NAMES_OFF "INFO_OFF + INFO_SIZE * 8"
xmath FOLDERS_OFF "NAMES_OFF + INFO_SIZE * 0x54"
It's still miles away from completing the script, though.
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: My first quickBMS script

Post by AnonBaiter »

Here I am with my shenanigans once again...

So I wrote this script:

Code: Select all

idstring "IOISNDSTREAM"
get VER long
get INFO_OFF long
get DUMMY1 long
if DUMMY1 == 0
   goto 0x18
   get DUMMY1 long
endif
goto INFO_OFF
for i = 0 < DUMMY1
   get UNK1 long
   get UNK2 long
   get OFFSET long
   get UNK4 long
   get SIZE long
   get UNK6 long
   get AUD_OFFSET long
   get UNK8 long
   get UNK9 long
   get UNK10 long
   get NAMESZ long
   get UNK12 long
   get NAME_OFFSET long
   get UNK14 long
   get LIP1 long
   get LIP2 long
   get LIP3 long
   get UNK18 long
   putarray 0 i AUD_OFFSET
   putarray 1 i NAME_OFFSET
   putarray 2 i NAMESZ
   putarray 3 i SIZE
   putarray 4 i OFFSET
   putarray 5 i LIP1
   putarray 6 i LIP3
next i
for i = 0 < DUMMY1
   getarray NAME_OFFSET 1 i
   getarray NAMESZ      2 i
   savepos TMP
   goto NAME_OFFSET
   getdstring NAME NAMESZ
   goto TMP
   putarray 7 i NAME
next i
for i = 0 < DUMMY1
   getarray AUD_OFFSET 0 i
   getarray SIZE       3 i
   getarray OFFSET     4 i
   getarray LIP1       5 i
   getarray LIP3       6 i
   getarray NAME       7 i
   goto AUD_OFFSET
   get CODEC long
   get AUD2 long
   get CHANNELS long
   get FREQUENCY long
   get BITS long
   get INTERLEAVE long
   get AUD7 long
   if LIP1 == 0x4
      math OFFSET += 0x1000
   endif
   if LIP3 == 0x1
   elif LIP3 == 0x2
      math OFFSET += 0x1000
   endif
   if CODEC == 0x2 |Z CODEC == 0xa
      callfunction PCM_1
   elif CODEC == 0x3
      set GENH_CODEC long 0xf
      callfunction GENH
   elif CODEC == 0x4
      string NAME R= ".wav" ".ogg"
      log NAME OFFSET SIZE
   elif COCEC == 0xb
      set GENH_CODEC long 0x0
      callfunction GENH
   elif CODEC == 0x11
      callfunction PCM_2
   else
      log NAME OFFSET SIZE
   endif
next i

startfunction PCM_1
   getarray SIZE 3 i
    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\x00\x00\x00\x00"

    set RIFFSIZE long SIZE
    math RIFFSIZE += 36
    set BLOCKALIGN long BITS
    set AVGBYTES long 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

    log MEMORY_FILE2 0 44 MEMORY_FILE
    append
    log MEMORY_FILE2 OFFSET SIZE
    append
    get RIFF_SIZE asize MEMORY_FILE2
    log NAME 0 RIFF_SIZE MEMORY_FILE2
endfunction

startfunction PCM_2
   getarray SIZE 3 i
    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\x00\x00\x00\x00"

    set RIFFSIZE long SIZE
    math RIFFSIZE += 36
    set BLOCKALIGN long BITS
    set AVGBYTES long 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

    log MEMORY_FILE2 0 44 MEMORY_FILE
    append
    log MEMORY_FILE2 OFFSET SIZE
    append
    get RIFF_SIZE asize MEMORY_FILE2
   string NAME += ".wav"
    log NAME 0 RIFF_SIZE MEMORY_FILE2
endfunction

startfunction GENH
   set SAMPLES SIZE
   math SAMPLES *= 8
   math SAMPLES /= BITS

   set FSIZE SIZE
   math FSIZE += 0x1000
   putVarChr MEMORY_FILE FSIZE 0
   log MEMORY_FILE 0 0
   putVarChr MEMORY_FILE 0 0x484e4547 long
   putVarChr MEMORY_FILE 0x4 CHANNELS long
   putVarChr MEMORY_FILE 0x8 INTERLEAVE long
   putVarChr MEMORY_FILE 0xc FREQUENCY long
   putVarChr MEMORY_FILE 0x10 0xffffffff long
   putVarChr MEMORY_FILE 0x14 SAMPLES long
   putVarChr MEMORY_FILE 0x18 GENH_CODEC long
   putVarChr MEMORY_FILE 0x1c 0x1000 long # offset; == stream start if no header
   putVarChr MEMORY_FILE 0x20 0x1000 long
   putVarChr MEMORY_FILE 0x300 FSIZE long
   putVarChr MEMORY_FILE 0x304 0x32304756 long
   putVarChr MEMORY_FILE 0xfff 0 byte
   math FSIZE -= 0x1000
   append
   log MEMORY_FILE OFFSET FSIZE
   append
   get SIZE asize MEMORY_FILE
   string NAME R= ".wav" ".genh"
   log NAME 0 SIZE MEMORY_FILE
endfunction
And so far I'm using the "set GENH_CODEC long" variable/argument, then I set the hexadecimal number the output file should be written with as .genh. Well, it works with 0xf for the most part but it somehow doesn't with 0x0(see PS3_Def.txt and compare it with pc_def.txt if you know what I mean). What should I do about this?
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: My first quickBMS script

Post by AnonBaiter »

So, I wrote a script for the .hpk file...

Code: Select all

# LEVEL-5 PS3 .hpk format
# work-in-progress

endian big

math OFFSET = 0
callfunction EXTRACT_HPK 1

startfunction EXTRACT_HPK
   savepos BACKUP_OFF
   goto OFFSET
   savepos HPK_OFF
   idstring "01PH"
   get FILES long
   get DUMMY1 long
   get DUMMY2 long
   get NAMES_OFF long
   get BASE_OFF long
   get DUMMY5 short
   get DUMMY6 short
   get DUMMY7 long
   math BASE_OFF + HPK_OFF
   for i = 0 < FILES
      getdstring HASH1 0x10
      get OFFSET long
      get SIZE long
      get NAME_OFF long
      get HASH2 long
      if OFFSET != 0xffffffff
         if NAME_OFF == 0xffffffff
            set NAME string ""
         else
            savepos TMP
            math NAME_OFF + NAMES_OFF
            goto NAME_OFF
            get NAME string
            goto TMP
         endif
         math OFFSET + BASE_OFF
         set EXT extension NAME
         if EXT == "hpk"
            callfunction EXTRACT_HPK
         else
            log NAME OFFSET SIZE
         endif
      endif
   next i
   goto BACKUP_OFF
endfunction
The thing is, there is also a .hpk file inside an .hpk file. However, when NAME_OFF references that offset in which there isn't even a name available, this is where things get weird. Observe:

Code: Select all

. 000001e0 getdstr HASH1      "" 16
    c7 7f 0c 43 b1 a2 16 30 3b de db cd a8 36 5d 40   ...C...0;....6]@
. 000001f0 get     OFFSET     0x00000000 4
. 000001f4 get     SIZE       0x00000100 4
. 000001f8 get     NAME_OFF   0x00000000 4
. 000001fc get     HASH2      0x48b763dc 4
. 00000080 get     NAME       "" -1
  000000c0 256        caþ‡_À¸’_6r~¨ÐÛ
So far, this issue is only affected in .hpk files, there's no other file that gets this oddity that I know of.
Are there any solutions for this?
StreamThread
Posts: 54
Joined: Fri May 27, 2016 2:28 pm

Re: My first quickBMS script

Post by StreamThread »

How is possible extract chunks from resource file, if from it known only compressed size but not uncompressed? Clog function always saying what uncompressed size is bugger than the allocated buffer. Comtype is Zlib.

Manually, every "cuted" chunk successfully extracting with offzip.
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: My first quickBMS script

Post by AnonBaiter »

I don't have any ideas as of now.
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: My first quickBMS script

Post by AnonBaiter »

So, I wrote this script for the bigfile.### files stored in the Xbox version of Legacy of Kain Defiance:

Code: Select all

# Legacy of Kain Defiance (PS2, XBOX)

get EXT extension
if EXT == "000"
    # necessary because sortarray is signed
    math TMP = 0x10000000
    math TMP *= 16
    if TMP == 0
        print "you must use quickbms_4gb_files.exe with big archives"
        cleanexit
    endif
endif
get FILES long
endian guess FILES
for i = 0 < FILES
   get NAME_CRC long
   putarray 0 i NAME_CRC
next i
for i = 0 < FILES
   get SIZE long
   get OFFSET long
   get ZSIZE long
   if EXT == "000"
      putarray 1 i SIZE
      putarray 2 i OFFSET
      putarray 3 i ZSIZE
   else
      if ZSIZE == 0
         log "" OFFSET SIZE
      else
         clog "" OFFSET ZSIZE SIZE
      endif
   endif
next i
if EXT == "000"
    print "sorting... wait less than one minute..."
    sortarray 0 1
    math ARCHIVE_NUM = 0
    math ARCHIVE_OFF = 0
    get ARCHIVE_SIZE asize
    for i = 0 < FILES
      getarray NAME_CRC  0 i
        getarray SIZE      1 i
        getarray OFFSET    2 i
      getarray ZSIZE     3 i
        math TMP_OFF = OFFSET
        math OFFSET - ARCHIVE_OFF
        if OFFSET u>= ARCHIVE_SIZE
            math ARCHIVE_NUM + 1
            string EXT p "%03d" ARCHIVE_NUM
            open FDDE EXT
            math ARCHIVE_OFF + OFFSET
            get ARCHIVE_SIZE asize
            math OFFSET = 0
        endif
      if ZSIZE == 0
         log "" OFFSET SIZE
      else
         clog "" OFFSET ZSIZE SIZE
      endif
    next i
endif
And the issue I`m having is this:
QuickBMS generic files extractor and reimporter 0.7.7 (64bit test)
by Luigi Auriemma
e-mail: me@aluigi.org
web: aluigi.org
(Dec 3 2016 - 21:43:01)

quickbms.aluigi.org Homepage
zenhax.com ZenHAX Forum
@zenhax Twitter & Scripts

- current_folder: C:\Documents and Settings\AnonBaiter\Desktop\quickbms
- bms_folder: C:\Documents and Settings\AnonBaiter\Desktop\quickbms
- exe_folder: C:\Documents and Settings\AnonBaiter\Desktop\quickbms
- file_folder: E:\XBOX
- output_folder: .
- temp_folder: C:\DOCUME~1\ANONBA~1\LOCALS~1\Temp\
- open input file E:\XBOX\bigfile.000
- open script C:\Documents and Settings\AnonBaiter\Desktop\quickbms\legacy_of_ka
in_defiance.bms
- set output folder .

offset filesize filename
--------------------------------------
- enter in folder E:\XBOX
coverage file 0 0% 211444 156790784 . offset 00000000000339f4
- open input file E:\XBOX\bigfile.001
- enter in folder E:\XBOX
coverage file 0 0% 0 150968320 . offset 0000000000000000
- open input file E:\XBOX\bigfile.002
- enter in folder E:\XBOX
coverage file 0 0% 0 156438528 . offset 0000000000000000
- open input file E:\XBOX\bigfile.003
- enter in folder E:\XBOX
coverage file 0 0% 0 148822016 . offset 0000000000000000
- open input file E:\XBOX\bigfile.004
- enter in folder E:\XBOX
coverage file 0 0% 0 150833152 . offset 0000000000000000
- open input file E:\XBOX\bigfile.005
- enter in folder E:\XBOX
coverage file 0 0% 0 151306240 . offset 0000000000000000
- open input file E:\XBOX\bigfile.006
- enter in folder E:\XBOX
coverage file 0 0% 0 152500224 . offset 0000000000000000
- open input file E:\XBOX\bigfile.007
- enter in folder E:\XBOX
coverage file 0 0% 0 153606144 . offset 0000000000000000
- open input file E:\XBOX\bigfile.008
- enter in folder E:\XBOX
coverage file 0 0% 0 154140672 . offset 0000000000000000
- open input file E:\XBOX\bigfile.009
- enter in folder E:\XBOX
coverage file 0 0% 0 155459584 . offset 0000000000000000
- open input file E:\XBOX\bigfile.010
- enter in folder E:\XBOX
coverage file 0 0% 0 150982656 . offset 0000000000000000
- open input file E:\XBOX\bigfile.011
- enter in folder E:\XBOX
coverage file 0 0% 0 156151808 . offset 0000000000000000
- open input file E:\XBOX\bigfile.012
- enter in folder E:\XBOX
coverage file 0 0% 0 157239296 . offset 0000000000000000
- open input file E:\XBOX\bigfile.013
- enter in folder E:\XBOX
coverage file 0 0% 0 156991488 . offset 0000000000000000
- open input file E:\XBOX\bigfile.014
- enter in folder E:\XBOX
coverage file 0 0% 0 154460160 . offset 0000000000000000
- open input file E:\XBOX\bigfile.015
- enter in folder E:\XBOX
coverage file 0 0% 0 136067072 . offset 0000000000000000
- open input file E:\XBOX\bigfile.016
- enter in folder E:\XBOX
coverage file 0 0% 0 137801728 . offset 0000000000000000
- open input file E:\XBOX\bigfile.017
- enter in folder E:\XBOX
coverage file 0 0% 0 156495872 . offset 0000000000000000
- open input file E:\XBOX\bigfile.018
- enter in folder E:\XBOX
coverage file 0 0% 0 156962816 . offset 0000000000000000
- open input file E:\XBOX\bigfile.019
- enter in folder E:\XBOX
coverage file 0 0% 0 155133952 . offset 0000000000000000
- open input file E:\XBOX\bigfile.020
- enter in folder E:\XBOX
coverage file 0 0% 0 154263552 . offset 0000000000000000
- open input file E:\XBOX\bigfile.021
- enter in folder E:\XBOX
coverage file 0 0% 0 99928064 . offset 0000000000000000
- open input file E:\XBOX\bigfile.022

- error in src\file.c line 247: fdnum_open()
Error: No such file or directory

Last script line before the error or that produced the error:
51 open FDDE EXT
The thing is, the script tries to find a splitted archive file(bigfile.022) that doesn`t exist, and rather than locate the bigfile.### number based on the offset like it does in tomb_raider_legend.bms, it just loads one bigfile.### file after another, which led me to this issue. What should I do to avoid this?

Here`s an attached debug report.