Skip to content
View in the app

A better way to browse. Learn more.

ResHax

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.
Help us keep the site running.

Star Trek: Conquest (Wii) - Music.WSB/.WSS

Featured Replies

  • Author
  • Localization

AlphaTwentyThree, posted Mon May 16, 2016 12:11 pm (13450)


No ideas? :\
  • Author
  • Localization

aluigi, posted Sun May 29, 2016 8:56 pm (13793)


http://aluigi.org/bms/stc_wsb_wss.bms
This is not my field but I suspect that those 32bytes handled by the script as COEFF may be the coefficient data used in Nintendo adpcm... anyway now it's your job :)
  • Author
  • Localization

AlphaTwentyThree, posted Mon May 30, 2016 11:46 am (13807)


All streams have a looped section and an intro section. The problem is that the number of samples is the same for both of these, which is obviously wrong but it's saved like this in the header. The correct nos is nowhere to be found. The offsets have to be corrected by 0x80 in order for the streams to work. Also, there was a little mistake in your script: you wrote i 1 but didn't write i-1 afterwards. ;)
So well, here's my script that automatically adds genh headers. The streams all work (mono though) but of course the intro sections are missing the correct number of samples.
Code:
old script erroneous, corrected script pending
  • Author
  • Localization

AlphaTwentyThree, posted Mon May 30, 2016 11:48 am (13808)


I just noticed that the files aren't played correctly, so we'll wait till I've figured out how to deal with them
  • Author
  • Localization

AlphaTwentyThree, posted Mon May 30, 2016 12:18 pm (13809)


Ok, I essentially know how the system works. Actually those "intro" files are the first interleave block of a stereo file. So 1/2, 3/4 and so on belong together with size(1) being the stereo interleave. I'll implement it tonight.
  • Author
  • Localization

AlphaTwentyThree, posted Mon May 30, 2016 12:26 pm (13810)


Tested manually and it works. Implentation following...
  • Author
  • Localization

AlphaTwentyThree, posted Mon May 30, 2016 7:30 pm (13816)


OH. MY. GOD! What a hazzle to get all the things working. It was actually more complicated than I thought. The section starting at 0x324 in the wsb file actually contains a list of parts that belong together, so in this case it's either mono or stereo. The FILES variable is actually the PARTS variable (0x4a) and the file number is at 4 in the wsb (0x26). There are two mono files that have 0xcdcdcdcd as their second part, so that's the identifier.
I didn't want to put everything in one script because that would be too confusing. Instead, I merged the parts that belong together and created a pseudo-header that depicts the channels, number of samples, frequency and one or two decoding coefficients. The second script either makes a simple mono GENH if the file is mono and for the stereo files, well, a re-interleave: Deinterleaving the whole stream with the given interleave (in this case the size of the first part), re-interleaving it and adding a genh header.
So, without further ado, here are both scripts:
Code:
# Star Trek: Conquest (WSB/WSS)
# script for QuickBMS http://quickbms.aluigi.org
# base written by Aluigi - thanks! :)
# corrections written by AlphaTwentyThree
# note that the extracted files only have a pseudo-header and need to be processed further

open FDDE "WSB"
open FDDE "WSS" 1

endian big
goto 0x4
get FILES long
goto 0xc
get PARTS long # entries / file parts
xmath INFO "0x14 * FILES 0x30"
goto INFO
for i = 0    get PART1 long
   get PART2 long
   getDstring DUMMY 0x1c
   putArray 0 i PART1
   putArray 1 i PART2
next i

for i = 0    getArray PART2 1 i
    get OFFSET1 long
   savepos DAT1
   getDstring H1 0x3c
   savepos MYOFF
   get OFFSET2 long
   savepos DAT2
   xmath SIZE1 "OFFSET2 - OFFSET1"
   getDstring H2 0x3c
   if PART2 != 0xcdcdcdcd # stereo
      set CH 2
      savepos MYOFF
   else # mono file
      set CH 1
      set OFFSET2 0
      set DAT2 0
      set SIZE2 0
   endif
   xmath n "i 1"
   if n != FILES
      get SIZE2 long
      goto MYOFF
   else
      get SIZE2 asize 1
   endif
   math SIZE2 -= OFFSET2
   xmath PSIZE "SIZE1 SIZE2 CH * 0x3c 4"
   putVarChr MEMORY_FILE PSIZE 0
   log MEMORY_FILE 0 0
   putVarChr MEMORY_FILE 0 SIZE1 long # interleave or stream size
   putVarChr MEMORY_FILE 4   CH long # channels
   append
   log MEMORY_FILE DAT1 0x3c
   if CH == 2
      log MEMORY_FILE DAT2 0x3c
   endif
   log MEMORY_FILE OFFSET1 SIZE1 1
   if CH == 2
      log MEMORY_FILE OFFSET2 SIZE2 1
   endif
   append
   get SIZE asize MEMORY_FILE
   get NAME basename
   string NAME p= "%s_%d.mus" NAME i
   log NAME 0 SIZE MEMORY_FILE
next i


The tricky but imaginative part is the savepos MYOFF at line 30. It is only overwritten in line 37 if the file is stereo. Otherwise the read data is discarded and the sizes for the second part set to zero. So the goto MYOFF in line 47 changes if the file is stereo or mono.
Also note the nifty little trick in the calculation of the preallocation size at line 52 where I just multiplied the 0x3c part with the channel count. :) (note that if the channels are 1, then SIZE2 is zero and doesn't add to the preallocation size).

And here's the second script to convert the mus files to playable genh:

Code:
# Star Trek: Conquest 
# converts *.mus with pseudo-headers to playable GENH files
# written by AlphaTwentyThree of Zenhax
# script for QuickBMS http://quickbms.aluigi.org

endian big
get INTSIZE long
get CH long
get NOS long
get DUMMY long
get FREQ long
savepos OFF_COEFF1
getDstring DUMMY 0x30
if CH == 2
   getDstring DUMMY 0xc
   savepos OFF_COEFF2
   set HEADER 0x80
elif CH == 1
   set OFF_COEFF2 OFF_COEFF1
   set HEADER 0x44
endif
set INTERLEAVE 4
endian little
if CH == 2
   set LAYERS 2
   set SPLIT_LAST_BLOCK 1
   set BLOCKSIZE 0

   xmath BLOCKSIZE "(INTSIZE * LAYERS)"
   set WSIZE INTSIZE
   get CYCLES asize
   xmath CYCLES "(CYCLES - HEADER) / BLOCKSIZE"

   get LASTBLOCK asize
   xmath LASTBLOCK "(LASTBLOCK - HEADER) % BLOCKSIZE"
   xmath LASTINT "LASTBLOCK / LAYERS"
   get PSIZE asize
   xmath PSIZE "(PSIZE - HEADER) / LAYERS"

   callfunction deinterleave 1

else
   log MEMORY_FILE2 0 0
   log MEMORY_FILE3 0 0
endif
callfunction GENH 1
if CH == 2
   callfunction reinterleave 1
else
   get SIZE asize
   math SIZE -= HEADER
   append
   log MEMORY_FILE HEADER SIZE
   append
endif

get SIZE asize MEMORY_FILE
get NAME basename
string NAME = ".genh"
log NAME 0 SIZE MEMORY_FILE

startfunction deinterleave
   xmath PSIZE "CYCLES * WSIZE LASTINT"
   for i = 1       if i == 1
         putVarChr MEMORY_FILE2 PSIZE 0
         log MEMORY_FILE2 0 0
      elif i == 2
         putVarChr MEMORY_FILE3 PSIZE 0
         log MEMORY_FILE3 0 0
      endif
      xmath BIAS_A "(i - 1) * WSIZE" # bias at start
      xmath BIAS_B "BLOCKSIZE - BIAS_A - WSIZE" # bias at end
   
      xmath RES_BIAS_A "(i - 1) * LASTINT"
      xmath RES_BIAS_B "LASTBLOCK - RES_BIAS_A - LASTINT"
      goto HEADER
      
      for k = 1          getDstring DUMMY BIAS_A
         getDstring WDATA WSIZE
         if i == 1
            putDstring WDATA WSIZE MEMORY_FILE2
         elif i == 2
            putDstring WDATA WSIZE MEMORY_FILE3
         endif
         getDstring DUMMY BIAS_B
      next k
      if LASTBLOCK != 0
         getDstring DUMMY RES_BIAS_A
         getDstring WDATA LASTINT
         if i == 1
            putDstring WDATA LASTINT MEMORY_FILE2
         elif i == 2
            putDstring WDATA LASTINT MEMORY_FILE3
         endif
         getDstring DUMMY RES_BIAS_B
      endif
   next i
endfunction

startfunction GENH
   get SIZE1 asize MEMORY_FILE2
   get SIZE2 asize MEMORY_FILE3
   xmath SIZE "SIZE1 SIZE2" # stream size
   xmath PRE_SIZE "SIZE 0xc0"
   putVarChr MEMORY_FILE SIZE 0
   log MEMORY_FILE 0 0

   putVarChr MEMORY_FILE 0 0x484e4547 long # "GENH"
   putVarChr MEMORY_FILE 4 CH long # ch
   putVarChr MEMORY_FILE 8 INTERLEAVE long # interleave
   putVarChr MEMORY_FILE 0xc FREQ long
   putVarChr MEMORY_FILE 0x10 0xffffffff long
   putVarChr MEMORY_FILE 0x14 NOS long # number of samples
   putVarChr MEMORY_FILE 0x18 0xc long # ?
   putVarChr MEMORY_FILE 0x1c 0xc0 long # stream start
   putVarChr MEMORY_FILE 0x20 0xc0 long # stream start
   putVarChr MEMORY_FILE 0x24 0x80 long # coeff1
   putVarChr MEMORY_FILE 0x28 0xa0 long # coeff2
   putVarChr MEMORY_FILE 0x2c 1 long
   putVarChr MEMORY_FILE 0x34 0x80 long # coeff1
   putVarChr MEMORY_FILE 0x38 0xa0 long # coeff2
   putVarChr MEMORY_FILE 0x7f 0 byte
   append
   log MEMORY_FILE OFF_COEFF1 0x20
   log MEMORY_FILE OFF_COEFF2 0x20
   append
endfunction

startfunction reinterleave
   get LOOPS asize MEMORY_FILE2
   xmath LOOPS "LOOPS / INTERLEAVE"
   set OFFSET 0
   for i = 1       goto OFFSET MEMORY_FILE2
      getdstring VAR INTERLEAVE MEMORY_FILE2
      putdstring VAR INTERLEAVE MEMORY_FILE
      goto OFFSET MEMORY_FILE3
      getdstring VAR INTERLEAVE MEMORY_FILE3
      putdstring VAR INTERLEAVE MEMORY_FILE
      math OFFSET = INTERLEAVE
   next i
endfunction
  • Author
  • Localization

aluigi, posted Tue May 31, 2016 5:29 pm (13837)


Excellent job :D
Guest
This topic is now closed to further replies.

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.