[SOLVED] Request to transcribe C code to QuickBMS

Programming related discussions related to game research
AlphaTwentyThree
Posts: 909
Joined: Sat Aug 09, 2014 11:21 am

[SOLVED] Request to transcribe C code to QuickBMS

Post by AlphaTwentyThree »

Hi there,

I'm not really familiar with C, so I'm asking for help here. I'm currently taking a look at the mjh/mjb pairs from Star Wars: Bounty Hunter (PS2). The format is implemented in vgmstream but there is name information in an external file that I would like to implement. For this, I need the mjb extracted so I can parse the names in. The vgmstream plugin just parses the mjb by splitting at certain offsets as the mjh doesn't have any info on that.
I'll need the following code in QuickBMS format:

Code: Select all

        int i;
        off_t subsong_offset = 0;

        total_subsongs = read_s32le(0x00,sh);
        if (target_subsong == 0) target_subsong = 1;
        if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;

        for (i = 0; i < total_subsongs; i++) {
            off_t offset = 0x40 + 0x40 * i;
            size_t subsong_size = read_u32le(offset + 0x08,sh) * read_u32le(offset + 0x10,sh) * read_u32le(offset + 0x14,sh);

            if (i + 1== target_subsong) {
                header_offset = offset;
                start_offset = subsong_offset;
            }
            subsong_offset += subsong_size;
        }

Thanks a lot!
Last edited by AlphaTwentyThree on Fri Jan 21, 2022 8:04 pm, edited 1 time in total.
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Request to transcribe C code to QuickBMS

Post by aluigi »

The first script I propose is just a mere reusage of the C code in quickbms with just some minimal changes for returning header_offset and start_offset other than subsong_offset.

Code: Select all

set MEMORY_FILE10 string "
typedef unsigned int    off_t;
typedef unsigned int    size_t;

int function(unsigned char *sh, int target_subsong, int *header_offset, int *start_offset) {
        int i;
        off_t subsong_offset = 0;

        int total_subsongs = *(int*)(0x00+sh);
        if (target_subsong == 0) target_subsong = 1;
        if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) return -1;

        for (i = 0; i < total_subsongs; i++) {
            off_t offset = 0x40 + 0x40 * i;
            size_t subsong_size = *(unsigned int *)(offset + 0x08+sh) * *(unsigned int *)(offset + 0x10+sh) * *(unsigned int *)(offset + 0x14+sh);

            if (i + 1== target_subsong) {
                *header_offset = offset;
                *start_offset = subsong_offset;
            }
            subsong_offset += subsong_size;
        }

        return subsong_offset;
}
"

get SIZE asize
log MEMORY_FILE 0 SIZE

math header_offset = 0
math start_offset  = 0
calldll MEMORY_FILE10 function tcc subsong_offset MEMORY_FILE 123 &header_offset &start_offset
print "%subsong_offset% %header_offset% %start_offset%"

This method is the best if you have no time and the code would be too slow in bms script.

The code is very simple so it's also possible to make a native bms script, give me some minutes.
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Request to transcribe C code to QuickBMS

Post by aluigi »

And this is the bms script:

Code: Select all

math header_offset = 0
math start_offset  = 0
math subsong_offset = 0

get total_subsongs long
if target_subsong == 0
    math target_subsong = 1
endif

getdstring DUMMY 0x3c   # 0x40 - 4
for i = 1 <= total_subsongs
    get DUMMY long      # 0x0
    get DUMMY long      # 0x4
    get NUM1 long       # 0x8
    get DUMMY long      # 0xc
    get NUM2 long       # 0x10
    get NUM3 long       # 0x14
    getdstring DUMMY 0x28   # 0x40 - 0x18

    xmath subsong_size "NUM1 * NUM2 * NUM3"

    if i == target_subsong
        math header_offset = offset
        math start_offset = subsong_offset
    endif
    math subsong_offset += subsong_size
next i

print "%subsong_offset% %header_offset% %start_offset%"
AlphaTwentyThree
Posts: 909
Joined: Sat Aug 09, 2014 11:21 am

Re: Request to transcribe C code to QuickBMS

Post by AlphaTwentyThree »

Thanks for that - however, it should be

Code: Select all

xmath subsong_size NUM1 * NUM2 * NUM3


Then everything fits. I basically needed an idea how the internal processing of vgmstream for a specific format was. Here's the script to get single tracks out of a mjh/mjb pair:

Code: Select all

open FDDE mjh 0
open FDDE mjb 1
get FILES long 0
goto 0x40 0
get BNAME basename
set OFFSET 0
for i = 1 <= FILES
   get UNK1 long 0
   get UNK2 long 0
   get CH long 0
   get FREQ long 0
   get INTERLEAVE long 0
   get BLOCKS long 0
   getDstring DUMMY 0x28
   xmath SIZE "CH * BLOCKS * INTERLEAVE"
   string NAME p "%s_%d" BNAME i
   callfunction SS2 1
   math OFFSET += SIZE
next i

startfunction SS2
   xmath PSIZE "SIZE + 0x28"
   putVarChr MEMORY_FILE PSIZE 0
   log MEMORY_FILE 0 0
   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"
   append
   log MEMORY_FILE OFFSET SIZE 1
   append
   putVarChr MEMORY_FILE 0x24 SIZE long
   putVarChr MEMORY_FILE 0xc FREQ long
   putVarChr MEMORY_FILE 0x14 INTERLEAVE long
   putVarChr MEMORY_FILE 0x10 CH byte
   #get SIZE asize MEMORY_FILE
   string NAME += ".ss2"
   log NAME 0 PSIZE MEMORY_FILE
endfunction
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Request to transcribe C code to QuickBMS

Post by aluigi »

Ah yeah it's a multiplication and not a sum... all those asterisks in the adapted C code that I used as base for the bms confused me ahahaha
I fixed the script