Anno: Create a new world (Wii) *.pak

Extraction and unpacking of game archives and compression, encryption, obfuscation, decoding of unknown files
AlphaTwentyThree
Posts: 909
Joined: Sat Aug 09, 2014 11:21 am

Anno: Create a new world (Wii) *.pak

Post by AlphaTwentyThree »

Hello there! Can you please take a look at the pak format from this game? I think the names are in the last file of the TOC at the end of the archive but I don't understand how they are related to the data. Here's a cut: http://www43.zippyshare.com/v/OvYoZd74/file.html
Thanks!
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Anno: Create a new world (Wii) *.pak

Post by aluigi »

AlphaTwentyThree
Posts: 909
Joined: Sat Aug 09, 2014 11:21 am

Re: Anno: Create a new world (Wii) *.pak

Post by AlphaTwentyThree »

Yes, that's what I got, too but take a look at the very last file, this could include the file names. Or am I wrong?
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Anno: Create a new world (Wii) *.pak

Post by aluigi »

Good catch, script 0.1.1.
Yeah it's a bit slow unfortunately.
AlphaTwentyThree
Posts: 909
Joined: Sat Aug 09, 2014 11:21 am

Re: Anno: Create a new world (Wii) *.pak

Post by AlphaTwentyThree »

Thanks! Do I need the sortarray or not? Because you put it in a comment...
AlphaTwentyThree
Posts: 909
Joined: Sat Aug 09, 2014 11:21 am

Re: Anno: Create a new world (Wii) *.pak

Post by AlphaTwentyThree »

I've just created a script to convert those *.ksnd RADP files to playable dsp L/R pairs if anyone is interested. It works on all but strangely exactly one file.

Code: Select all

idstring "RADP"
endian big
get LAYERS byte
get DUMMY byte
get INTSIZE short

if LAYERS == 1
   set OFFSET 0x20
   get SIZE asize
   math SIZE -= OFFSET
   get NAME basename
   string NAME += ".dsp"
   log NAME OFFSET SIZE
   cleanexit
elif LAYERS == 2
   set HEADER 0xe0
   set HSIZE 0x60
else
   print "Error: more than 2 layers! Aborting..."
   cleanexit
endif
   
set PRESERVE 1
set ADJUST 0
set SPLIT_LAST_BLOCK 1
set BLOCKSIZE 0 # size of one complete block
set SKIP_START 0 # area at start of each block to skip
set SKIP_END 0 # area at end of each block to skip

if BLOCKSIZE == 0
   xmath BLOCKSIZE "(INTSIZE * LAYERS) + SKIP_START + SKIP_END"
endif
if INTSIZE == 0
   xmath INTSIZE "BLOCKSIZE / LAYERS"
endif

xmath WSIZE "(BLOCKSIZE - SKIP_START - SKIP_END) / LAYERS" # data to write: (BLOCKSIZE - SKIP_START - SKIP_END)/LAYERS
get CYCLES asize
xmath CYCLES "(CYCLES - HEADER) / BLOCKSIZE"

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

callfunction testparameters 1
get EXT extension
callfunction deinterleave

startfunction testparameters
   # test 1: (BLOCKSIZE-SKIP_START-SKIP_END)/LAYERS must be integer (one block must be dividable into skip and layers)
   xmath TEST "BLOCKSIZE - SKIP_START - SKIP_END"
   math TEST %= LAYERS # single layer -> always ok
   if TEST != 0
      print "Error: blocksize minus skip isn't dividable by layer count! Aborting..."
      cleanexit
   endif
   
   # test 2: test for incomplete last block
   get TEST asize
   math TEST -= HEADER
   math TEST %= BLOCKSIZE
   if TEST != 0
      if SPLIT_LAST_BLOCK == 1
         print "Warning: file size minus header isn't dividable by blocksize! Last block will be equally split between layers!"
         print "Last chunks will have size of %LASTINT% bytes each."
      else
         print "ERROR: file size minus header isn't dividable by blocksize! Aborting..."
         cleanexit
      endif
   endif
   
   # test 3: ASIZE-HEADER-BLOCKSIZE must be greater null (at least one deinterleave cycle)
   get TEST asize
   xmath TEST "TEST - HEADER - BLOCKSIZE"
   if FSIZE <= 0
      print "Error: file too small to deinterleave! Aborting..."
      cleanexit
   endif
endfunction
   
startfunction deinterleave
   xmath PSIZE "CYCLES * WSIZE + LASTINT"
   if PRESERVE == 1
      math PSIZE += HSIZE # for each layer
   endif
   
   for i = 1 <= LAYERS
      putVarChr MEMORY_FILE PSIZE 0
      log MEMORY_FILE 0 0
      get NAME basename
      string NAME += "_"
      string NAME += i
      if PRESERVE == 1
         xmath GO "0x20 + ( i - 1 ) * HSIZE"
         goto GO
         getDstring HDATA HSIZE
         putDstring HDATA HSIZE MEMORY_FILE
      endif
      xmath BIAS_A "(i - 1) * WSIZE + SKIP_START"# bias at start
      xmath BIAS_B "BLOCKSIZE - BIAS_A - WSIZE" # bias at end
   
      xmath RES_BIAS_A "(i - 1) * LASTINT + SKIP_START"
      xmath RES_BIAS_B "LASTBLOCK - RES_BIAS_A - LASTINT"
      goto HEADER
      for k = 1 <= CYCLES
         getDstring DUMMY BIAS_A
         getDstring WDATA WSIZE
         putDstring WDATA WSIZE MEMORY_FILE
         getDstring DUMMY BIAS_B
      next k
      if LASTBLOCK != 0
         getDstring DUMMY RES_BIAS_A
         getDstring WDATA LASTINT
         putDstring WDATA LASTINT MEMORY_FILE
         getDstring DUMMY RES_BIAS_B
      endif
      get SIZE asize MEMORY_FILE
      get NAME basename
      if i = 1
         string NAME += "L.dsp"
      elif i = 2
         string NAME += "R.dsp"
      endif
      log NAME 0 SIZE MEMORY_FILE
   next i
endfunction


Here's the erroneous file: http://www10.zippyshare.com/v/6DCJCM7d/file.html
AlphaTwentyThree
Posts: 909
Joined: Sat Aug 09, 2014 11:21 am

Re: Anno: Create a new world (Wii) *.pak

Post by AlphaTwentyThree »

Just to let everybody know, this also works for "Secret Files: Tunguska" for Wii.
AlphaTwentyThree
Posts: 909
Joined: Sat Aug 09, 2014 11:21 am

Re: Anno: Create a new world (Wii) *.pak

Post by AlphaTwentyThree »

Actually it doesn't work for this file: http://www25.zippyshare.com/v/tjyBMXqb/file.html
Can you take another look into this please? Thanks.
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Anno: Create a new world (Wii) *.pak

Post by aluigi »

The problem is that the filenames are less than the files.
Script 0.2, select 'a' when it asks to overwrite the files.