# Yuke games: EPAC/EPK8 archives, PACH files and BPE chunks (script 0.2.1b) # note that this script is really big and chaotic and the function # which guesses the extension simply "guesses" it so don't consider it much # script for QuickBMS http://aluigi.org/papers.htm#quickbms comtype yuke_bpe putarray 0 0 0 # the following is only for being able to handle all the 3 files get NAME filename string NAME += ".unpacked" getdstring SIGN 4 if SIGN == "PACH" print "PACH file" get SIZE asize log MEMORY_FILE 0 SIZE callfunction pach_unpack cleanexit elif SIGN == "BPE " print "BPE chunk" get DUMMY long get ZSIZE long get SIZE long savepos OFFSET clog NAME OFFSET ZSIZE SIZE cleanexit endif set NAMESZ long 4 if SIGN == "EPAC" set NAMESZ long 4 elif SIGN == "EPK8" set NAMESZ long 8 else cleanexit endif #idstring "EPAC" print "EPAC archive" goto 0x800 for savepos OFFSET getdstring SIGN 4 if SIGN == "" cleanexit endif string SIGN -= 3 if SIGN == "E" # EMD, EVP, EVT, ED1 and so on get DUMMY long get DUMMY long else goto OFFSET getdstring NAME NAMESZ get OFFSET long get SIZE long math OFFSET += 8 # 0x4000 math OFFSET *= 0x800 math SIZE *= 0x100 log MEMORY_FILE OFFSET SIZE callfunction pach_unpack endif next startfunction pach_unpack set FOLDER string NAME getarray GLOBAL_COUNTER 0 0 if SIZE == 0 # will be fixed in the next quickbms # they are empty folders, so skip them #log NAME 0 SIZE elif SIZE < 8 log MEMORY_FILE2 0 SIZE MEMORY_FILE string NAME -= " " string NAME += / string NAME += GLOBAL_COUNTER callfunction gimme_a_name math GLOBAL_COUNTER += 1 putarray 0 0 GLOBAL_COUNTER else getdstring SIGN 4 MEMORY_FILE if SIGN == "PACH" get CHUNKS long MEMORY_FILE savepos INFO_OFF MEMORY_FILE math BASE_OFF = CHUNKS math BASE_OFF *= 12 math BASE_OFF += 8 for j = 0 < CHUNKS set NAME string FOLDER string NAME -= " " string NAME += / string NAME += GLOBAL_COUNTER goto INFO_OFF MEMORY_FILE get DUMMY long MEMORY_FILE get CHUNK_OFF long MEMORY_FILE get CHUNK_SIZE long MEMORY_FILE savepos INFO_OFF MEMORY_FILE math CHUNK_OFF += BASE_OFF goto CHUNK_OFF MEMORY_FILE getdstring SIGN 4 MEMORY_FILE if SIGN == "BPE " get DUMMY long MEMORY_FILE get ZSIZE long MEMORY_FILE get SIZE long MEMORY_FILE savepos OFFSET MEMORY_FILE clog MEMORY_FILE2 OFFSET ZSIZE SIZE MEMORY_FILE else log MEMORY_FILE2 CHUNK_OFF CHUNK_SIZE MEMORY_FILE math SIZE = CHUNK_SIZE endif callfunction gimme_a_name math GLOBAL_COUNTER += 1 putarray 0 0 GLOBAL_COUNTER next j else string NAME -= " " string NAME += / string NAME += GLOBAL_COUNTER log MEMORY_FILE2 0 SIZE MEMORY_FILE callfunction gimme_a_name math GLOBAL_COUNTER += 1 putarray 0 0 GLOBAL_COUNTER endif endif endfunction startfunction gimme_a_name get SIGN long MEMORY_FILE2 get SIGN2 long MEMORY_FILE2 if SIGN == 0x594f424a string NAME += ".YOBJ" log NAME 0 SIZE MEMORY_FILE2 elif SIGN == 0x20455042 string NAME += ".DAT" #get DUMMY long MEMORY_FILE2 get ZSIZE long MEMORY_FILE2 get SIZE long MEMORY_FILE2 savepos OFFSET MEMORY_FILE2 clog NAME OFFSET ZSIZE SIZE MEMORY_FILE2 elif SIGN == 0x34425346 string NAME += ".fsb" log NAME 0 SIZE MEMORY_FILE2 elif SIGN == 0x48434150 # memory_files are not recursive string NAME += ".PACH" log NAME 0 SIZE MEMORY_FILE2 elif SIGN == 0x20534444 string NAME += ".dds" log NAME 0 SIZE MEMORY_FILE2 elif SIGN & 0xffff0000 # guessed, should be good for the 99,9% of files string NAME += ".POF0" log NAME 0 SIZE MEMORY_FILE2 elif SIGN2 == 0x00000100 goto 0 MEMORY_FILE2 get TEXTURES long MEMORY_FILE2 goto 16 MEMORY_FILE2 for z = 0 < TEXTURES getdstring TEX_NAME 16 MEMORY_FILE2 if TEX_NAME == "" string NAME += ".TEX" log NAME 0 SIZE MEMORY_FILE2 math z = TEXTURES else getdstring TEX_EXT 4 MEMORY_FILE2 set TMP_NAME string FOLDER string TMP_NAME += / string TMP_NAME += TEX_NAME string TMP_NAME += "." string TMP_NAME += TEX_EXT get TEX_SIZE long MEMORY_FILE2 get TEX_OFFSET long MEMORY_FILE2 get DUMMY long MEMORY_FILE2 log TMP_NAME TEX_OFFSET TEX_SIZE MEMORY_FILE2 endif next z else string NAME += ".DAT" log NAME 0 SIZE MEMORY_FILE2 endif endfunction