├── README.md ├── amplitude_ark.bms ├── arika_ps2_cd.bms ├── atlantis_iii_ps2.bms ├── beenox_ps2.bms ├── bfps2_bfpsp_bfwii.bms ├── bge_mtx.bms ├── bigbag_dat.bms ├── chainall_toc_cin.bms ├── chase_the_express_dpf.bms ├── cing_fif_fpk.bms ├── current_status.md ├── dark_cloud.bms ├── darkest_of_days.bms ├── doom_3_bfg_edition.bms ├── driving_emotion_type-s.bms ├── dskimg_inf_bin.bms ├── dxmd_dxb_archive.bms ├── fbrb.bms ├── final_fantasy_xii.bms ├── frequency_ark.bms ├── front_mission_ps2_pos_dat.bms ├── gear_bigfile.bms ├── gnfs.bms ├── god-of-war-ii_ps2_toc.bms ├── god-of-war_ps2_toc.bms ├── god_of_war_wad.bms ├── gran_turismo_2.bms ├── gust_ps2.bms ├── half_life_ps2.bms ├── headhunter_ahff.bms ├── headhunter_pic.bms ├── hh2_ps2.bms ├── hh_ps2.bms ├── hype_the_time_quest_ps2_sound.bms ├── ico_df.bms ├── in2_tag_bin.bms ├── irxarc_bin.bms ├── james_camerons_avatar_the_game_pak.bms ├── kidou_senshi_gundam_ichinen_sensou.bms ├── killzone_beta.bms ├── kinetica_wad.bms ├── kojima_productions ├── README.md ├── kojima_productions_ps2_dat.bms ├── kojima_productions_ps2_ipk.bms └── metal_gear_solid_2_substance_xbox.bms ├── lair.bms ├── mgs2_stream.bms ├── mhw_chunk.bms ├── mhw_pkg.bms ├── microsoft_xbox.bms ├── moderngroove.bms ├── motor_toon_grand_prix.bms ├── musouorochi2hyper_wiiu_linkdata.bms ├── my_fitness_coach_pak.bms ├── namco_smv.bms ├── other_insanities ├── README.md └── nusound.txt ├── pants_pac.bms ├── polyphony_ps2vol.bms ├── reflections_img.bms ├── rmdp.bms ├── sally_bf.bms ├── scimitar[new_version] ├── scimitar_compressed_container.bms └── scimitar_new.bms ├── scimitar_alt.bms ├── seiken_densetsu_4.bms ├── shaun_white_snowboarding_fat_lin.bms ├── shellshock_nam67.bms ├── siren.bms ├── siren_2.bms ├── smash_court_pro_tournament.bms ├── sound_fat_big.bms ├── sound_fat_bin.bms ├── sqex_fse_fsd.bms ├── squaresoft-square.enix_sz_dat.bms ├── stuntman_xav.bms ├── sylpheed_ipfb.bms ├── tekken_tag_tournament.bms ├── tekken_tag_tournament_2.bms ├── the_bouncer.bms ├── this_is_football.bms ├── this_is_football_2002.bms ├── tri-ace_ps2.bms ├── tvdj_flk.bms ├── ubisoft_montreal_ps2_int.bms ├── ubisoft_sra.bms ├── valve_vpk.bms ├── virtuos_vbf.bms ├── x3_zpk.bms └── zone_of_the_enders.bms /README.md: -------------------------------------------------------------------------------- 1 | # le_quickbms_script_compendium 2 | 3 | right, first of all if you want to know how to use these scripts you better have this on your pocket by now 4 | 5 | aluigi.altervista.org/quickbms.htm 6 | 7 | after that you can just grab my scripts depending on what you want to use on quickbms 8 | 9 | i hope my scripts are actually useful to you 10 | 11 | oh yeah if you have anything else that could help me update my scripts a lot let me know 12 | 13 | ## a few tips for writing quickbms scripts 14 | 15 | multiplying/dividing a value to 2048(0x800) is the same as left-shifting/right-shifting a value to 11(0x0b), thus for a more simplified calc method(for example - an untouched CD/DVD sector offset) just use the latter 16 | -------------------------------------------------------------------------------- /amplitude_ark.bms: -------------------------------------------------------------------------------- 1 | # Amplitude (PS2) - main.ark 2 | 3 | open FDDE "ark" 0 4 | 5 | comtype gzip 6 | 7 | get ark_version long 8 | get ark_files long 9 | for i = 0 < ark_files 10 | get ark_02 long 11 | putarray 1 i ark_02 12 | get ark_03 long 13 | putarray 2 i ark_03 14 | get ark_04 long 15 | putarray 3 i ark_04 16 | get ark_05 long 17 | putarray 4 i ark_05 18 | get ark_06 long 19 | putarray 5 i ark_06 20 | next i 21 | get ark_name_size long 22 | savepos ark_pos_01 23 | xmath ark_pos_02 "ark_pos_01 + ark_name_size" 24 | goto ark_pos_02 25 | get ark_entries long 26 | for k = 0 < ark_entries 27 | get ark_08 long 28 | putarray 6 k ark_08 29 | next k 30 | 31 | for x = 0 < ark_files 32 | set file_name string "" 33 | getarray file_offset 1 x 34 | getarray string_id_01 2 x 35 | getarray string_id_02 3 x 36 | getarray file_size_if_normal_file 4 x 37 | getarray file_size_if_gzip_file 5 x 38 | for y = 0 < 2 39 | if y = 0 40 | getarray string_offset 6 string_id_02 41 | elif y = 1 42 | getarray string_offset 6 string_id_01 43 | endif 44 | math string_offset + ark_pos_01 45 | goto string_offset 46 | get name_string string 47 | string file_name + / 48 | string file_name + name_string 49 | next y 50 | if file_size_if_gzip_file != 0 51 | set file_name_without_the_gz string file_name 52 | string file_name_without_the_gz > ".gz" 53 | clog file_name_without_the_gz file_offset file_size_if_normal_file file_size_if_gzip_file 54 | else 55 | log file_name file_offset file_size_if_normal_file 56 | endif 57 | next x 58 | -------------------------------------------------------------------------------- /arika_ps2_cd.bms: -------------------------------------------------------------------------------- 1 | # Arika - ARIKA.DAT/INFO.DAT 2 | # --- 3 | # Street Fighter EX3 (PS2) 4 | # Technictix (PS2) 5 | # Technic Beat (PS2) 6 | # Forever Blue (Wii) 7 | # Forever Blue: Umi no Yubigoe (Wii) 8 | 9 | math dat1 = 1 10 | math dat2 = 2 11 | math ver = 1 12 | math is_elf = 1 13 | get elf_name filename 14 | if elf_name == "SLPM_601.05" # Street Fighter EX3 - Trial Version (PlayStation Festival 2000) 15 | xmath files "0x1a00 / 0x20" 16 | callfunction handle_arika_dat 1 17 | goto 0x3fff40 18 | callfunction txth_handling_for_sfex3 1 19 | elif elf_name == "SLPS_200.03" # Street Fighter EX3 - Final Product (Japan) 20 | xmath files "0x48c0 / 0x20" 21 | callfunction handle_arika_dat 1 22 | goto 0x433790 23 | callfunction txth_handling_for_sfex3 1 24 | elif elf_name == "SLPM_601.34" # Technictix - Trial Version (Japan) 25 | xmath files "0xda0 / 0x20" 26 | callfunction handle_arika_dat 1 27 | elif elf_name == "SLPS_200.55" # Technictix - Final Product (Japan) 28 | xmath files "0x2fc0 / 0x20" 29 | callfunction handle_arika_dat 1 30 | endif 31 | 32 | startfunction handle_arika_dat 33 | if is_elf = 0 34 | if dat_name == "ARIKA.DAT" 35 | open FDSE "ARIKA.DAT" dat1 36 | open FDSE "PS2.DAT" dat2 37 | elif dat_name == "INFO.DAT" 38 | open FDSE "INFO.DAT" dat1 39 | open FDSE "GAME.DAT" dat2 40 | endif 41 | else 42 | # i don't know! 43 | open FDSE "ARIKA.DAT" dat1 44 | open FDSE "PS2.DAT" dat2 45 | endif 46 | get arika_dat_size asize dat1 47 | goto 0 dat1 48 | if ver = 2 49 | get is_encrypted byte dat1 50 | goto 0 dat1 51 | endif 52 | if is_encrypted == 0 53 | # (todo) 54 | else 55 | for i = 0 < 0x10 56 | get k1 byte dat1 57 | xmath k2 "(k1 ^ 0xff) & 0xff" 58 | putarray 0 i k2 59 | next i 60 | if is_elf = 0 61 | math pos_02 = 0x20 62 | goto pos_02 dat1 63 | math files = 0 64 | if ver = 1 65 | xmath bytes_to_process "(arika_dat_size - pos_02) / 0x20" 66 | for i2 = 0 < bytes_to_process 67 | get tb01 long dat1 68 | get tb02 long dat1 69 | get tb03 long dat1 70 | get tb04 long dat1 71 | get tb05 long dat1 72 | get tb06 long dat1 73 | get tb07 long dat1 74 | get tb08 long dat1 75 | if tb01 != 0x40404040 76 | if tb05 != 0x40404040 77 | math files + 1 78 | endif 79 | endif 80 | next i2 81 | endif 82 | endif 83 | math pos_01 = 0x10 84 | xmath bytes_to_process "(arika_dat_size - pos_01) / 0x10" 85 | log MEMORY_FILE 0 0 86 | goto 0 MEMORY_FILE 87 | for i2 = 0 < bytes_to_process 88 | for j1 = 0 < 0x10 89 | goto pos_01 dat1 90 | get target byte dat1 91 | xmath d1 "(target & 0xf) << 4 | (target >> 4) & 0x0f" 92 | getarray key 0 j1 93 | xmath d2 "(key - d1) & 0xff" 94 | put d2 byte MEMORY_FILE 95 | math pos_01 + 1 96 | next j1 97 | next i2 98 | putarray 0 "" "" 99 | goto 0 dat1 100 | getdstring arika_title 0x10 dat1 101 | if ver = 1 102 | goto 0 MEMORY_FILE 103 | goto 4 MEMORY_FILE 104 | get base_sector_for_ps2_dat long MEMORY_FILE 105 | goto 0x10 MEMORY_FILE 106 | elif ver = 2 107 | goto 0x1c MEMORY_FILE 108 | get files long MEMORY_FILE 109 | goto 0x20 MEMORY_FILE 110 | endif 111 | for i = 0 < files 112 | math do_not_extract = 0 113 | if ver = 1 114 | getdstring file_name 0x14 MEMORY_FILE 115 | get file_offset long MEMORY_FILE 116 | math file_offset - base_sector_for_ps2_dat 117 | math file_offset << 11 118 | get file_size_in_sectors long MEMORY_FILE 119 | get file_size long MEMORY_FILE 120 | elif ver = 2 121 | getdstring file_name 0x20 MEMORY_FILE 122 | get file_size_01 long MEMORY_FILE 123 | get file_offset long MEMORY_FILE 124 | math file_offset << 11 125 | get file_size_in_sectors long MEMORY_FILE 126 | get file_size_02 long MEMORY_FILE 127 | endif 128 | string final_name p "%s\%s" arika_title file_name 129 | if ver = 2 130 | if file_size_01 != file_size_02 131 | print " compressed file %final_name% with unknown compression algorithm. " 132 | math do_not_extract = 1 133 | else 134 | math file_size == file_size_02 135 | endif 136 | endif 137 | if do_not_extract = 0 138 | log final_name file_offset file_size dat2 139 | endif 140 | next i 141 | endif 142 | endfunction 143 | 144 | # the executable part is just for handling .mus files as used by the game. 145 | 146 | startfunction txth_handling_for_sfex3 147 | xmath mus_entries "0xa8 / 0xc" 148 | for i = 0 < mus_entries 149 | get mus_name_offset long 150 | math mus_name_offset - 0xfff00 151 | putarray 0 i mus_name_offset 152 | get num_songs short 153 | putarray 1 i num_songs 154 | get mus_size short 155 | putarray 2 i mus_size 156 | get mus_04 long 157 | putarray 3 i mus_04 158 | next i 159 | math sample_rate = 0xac44 160 | math interleave = 0x8000 161 | math channels = 2 162 | xmath chunk_size "interleave * channels" 163 | for i = 0 < mus_entries 164 | log MEMORY_FILE 0 0 165 | getarray mus_name_offset 0 i 166 | goto mus_name_offset 167 | get mus_name string 168 | getarray num_songs 1 i 169 | getarray mus_size 2 i 170 | getarray mus_04 3 i 171 | putct "codec = PSX" string -1 MEMORY_FILE 172 | string txth_l2 p "sample_rate = %d" sample_rate 173 | put 0x0d byte MEMORY_FILE 174 | put 0x0a byte MEMORY_FILE 175 | putct txth_l2 string -1 MEMORY_FILE 176 | string txth_l3 p "channels = %d" channels 177 | put 0x0d byte MEMORY_FILE 178 | put 0x0a byte MEMORY_FILE 179 | putct txth_l3 string -1 MEMORY_FILE 180 | string txth_l4 p "interleave = %d" interleave 181 | put 0x0d byte MEMORY_FILE 182 | put 0x0a byte MEMORY_FILE 183 | putct txth_l4 string -1 MEMORY_FILE 184 | string txth_l5 p "subsong_count = %d" num_songs 185 | put 0x0d byte MEMORY_FILE 186 | put 0x0a byte MEMORY_FILE 187 | putct txth_l5 string -1 MEMORY_FILE 188 | string txth_l6 p "chunk_start = 0" 189 | put 0x0d byte MEMORY_FILE 190 | put 0x0a byte MEMORY_FILE 191 | putct txth_l6 string -1 MEMORY_FILE 192 | string txth_l7 p "chunk_size = %d" chunk_size 193 | put 0x0d byte MEMORY_FILE 194 | put 0x0a byte MEMORY_FILE 195 | putct txth_l7 string -1 MEMORY_FILE 196 | string txth_l8 p "chunk_count = %d" num_songs 197 | put 0x0d byte MEMORY_FILE 198 | put 0x0a byte MEMORY_FILE 199 | putct txth_l8 string -1 MEMORY_FILE 200 | string txth_l9 p "start_offset = 0" 201 | put 0x0d byte MEMORY_FILE 202 | put 0x0a byte MEMORY_FILE 203 | putct txth_l9 string -1 MEMORY_FILE 204 | xmath num_samples "mus_size * chunk_size" 205 | math num_samples / 2 206 | math num_samples / 16 207 | math num_samples * 28 208 | string txth_l10 p "num_samples = %d" num_samples 209 | put 0x0d byte MEMORY_FILE 210 | put 0x0a byte MEMORY_FILE 211 | putct txth_l10 string -1 MEMORY_FILE 212 | string txth_name p "txth\%s.txth" mus_name 213 | get txth_size asize MEMORY_FILE 214 | log txth_name 0 txth_size MEMORY_FILE 215 | next i 216 | endfunction 217 | 218 | math dat1 = 0 219 | math dat2 = 1 220 | math is_elf = 0 221 | get dat_name filename 222 | if dat_name == "ARIKA.DAT" 223 | open FDSE "PS2.DAT" 1 224 | math ver = 1 225 | callfunction handle_arika_dat 1 226 | elif dat_name == "INFO.DAT" 227 | open FDSE "GAME.DAT" 1 228 | math ver = 2 229 | callfunction handle_arika_dat 1 230 | endif 231 | -------------------------------------------------------------------------------- /atlantis_iii_ps2.bms: -------------------------------------------------------------------------------- 1 | # Atlantis III - The New World (PS2) - big.[dir+dat] 2 | 3 | get ext extension 4 | if ext == "dir" 5 | open FDDE "dat" 1 6 | math filenum = 0 7 | math datnum = 1 8 | elif ext == "dat" 9 | open FDDE "dir" 1 10 | math filenum = 1 11 | math datnum = 0 12 | else 13 | cleanexit 14 | endif 15 | 16 | math dir_pos = 0 17 | math dir_num = 0 18 | math processed_pos = 0 19 | math processed_dir = 0 20 | math processed_dat = 0 21 | math files = 0 22 | for j = 0 < 8 23 | putarray 0 j 0 24 | putarray 1 j 0 25 | putarray 2 j 0 26 | putarray 3 j 0 27 | putarray 4 j "" 28 | next j 29 | get dat_size asize datnum 30 | goto dir_pos filenum 31 | get dir_pos long filenum 32 | callfunction handle_dir 1 33 | 34 | startfunction handle_dir 35 | for 36 | goto dir_pos filenum 37 | get next_dir_pos long filenum 38 | get upcoming_dir_pos long filenum 39 | get file_info_pos long filenum 40 | get dir_name_pos long filenum 41 | savepos processed_pos filenum 42 | if processed_dir = 1 43 | if next_dir_pos != 0 44 | math dir_pos == next_dir_pos 45 | math processed_dir = 0 46 | callfunction handle_dir 1 47 | else 48 | xmath prev_dir "dir_num - 1" 49 | if prev_dir > 0 50 | getarray upcoming_dir_pos 0 prev_dir 51 | getarray next_dir_pos 1 prev_dir 52 | getarray file_info_pos 2 prev_dir 53 | getarray dir_pos 3 prev_dir 54 | getarray dir_name 4 prev_dir 55 | math dir_num = prev_dir 56 | math processed_dir = 1 57 | callfunction handle_dir 1 58 | endif 59 | endif 60 | endif 61 | savepos temp_01 filenum 62 | goto dir_name_pos filenum 63 | get dir_name string filenum 64 | goto temp_01 filenum 65 | putarray 0 dir_num upcoming_dir_pos 66 | putarray 1 dir_num next_dir_pos 67 | putarray 2 dir_num file_info_pos 68 | putarray 3 dir_num dir_pos 69 | putarray 4 dir_num dir_name 70 | if file_info_pos != 0 71 | math file_info_curr_pos = file_info_pos 72 | for 73 | math keywords = 2 74 | goto file_info_curr_pos filenum 75 | get next_file_info_pos long filenum 76 | get file_name_pos long filenum 77 | savepos temp_02 filenum 78 | goto file_name_pos filenum 79 | get file_name string filenum 80 | goto temp_02 filenum 81 | get file_offset long filenum 82 | get file_size long filenum 83 | math keywords + dir_num 84 | xmath last_kw "keywords - 1" 85 | set full_name string "" 86 | for x = 0 < keywords 87 | if x != last_kw 88 | getarray kw1 4 x 89 | else 90 | set kw1 string file_name 91 | endif 92 | string full_name + kw1 93 | if x != last_kw 94 | string full_name + "\" 95 | endif 96 | next x 97 | log full_name file_offset file_size datnum 98 | math files + 1 99 | xmath sz1 "file_size / 0x800" 100 | xmath sz2 "file_size % 0x800" 101 | if sz2 != 0 102 | math sz1 + 1 103 | endif 104 | math sz1 * 0x800 105 | math processed_dat += sz1 106 | savepos processed_pos filenum 107 | if next_file_info_pos != 0 108 | math file_info_curr_pos == next_file_info_pos 109 | else 110 | break 111 | endif 112 | next 113 | endif 114 | if processed_dat == dat_size 115 | # what this is is a hacky method that forces the script to quit 116 | # once it's done going through all the files listed in this big.dir file 117 | # it was either that or have the script process big.dir forever 118 | cleanexit 119 | endif 120 | if upcoming_dir_pos != 0 121 | math dir_num + 1 122 | math dir_pos == upcoming_dir_pos 123 | callfunction handle_dir 1 124 | else 125 | if next_dir_pos != 0 126 | math dir_pos == next_dir_pos 127 | callfunction handle_dir 1 128 | else 129 | xmath prev_dir "dir_num - 1" 130 | if prev_dir > 0 131 | getarray upcoming_dir_pos 0 prev_dir 132 | getarray next_dir_pos 1 prev_dir 133 | getarray file_info_pos 2 prev_dir 134 | getarray dir_pos 3 prev_dir 135 | getarray dir_name 4 prev_dir 136 | math dir_num = prev_dir 137 | math processed_dir = 1 138 | callfunction handle_dir 1 139 | endif 140 | endif 141 | endif 142 | next 143 | endfunction 144 | -------------------------------------------------------------------------------- /beenox_ps2.bms: -------------------------------------------------------------------------------- 1 | # Bee Movie Game (PS2) 2 | 3 | get exe_name filename 4 | 5 | if exe_name == "SLUS_216.22" 6 | callfunction parse_beenox_beemoviegame_data 1 7 | elif exe_name == "SLES_550.16" 8 | callfunction parse_beenox_beemoviegame_data 1 9 | endif 10 | 11 | startfunction parse_beenox_beemoviegame_data 12 | goto 0x14c300 13 | get files long 14 | goto 0x140820 15 | for i = 0 < files 16 | getdstring file_name 0x100 17 | getdstring archive_name 0x100 18 | get file_offset long 19 | get file_size long 20 | open FDSE archive_name 1 21 | log file_name file_offset file_size 1 22 | next i 23 | endfunction 24 | -------------------------------------------------------------------------------- /bge_mtx.bms: -------------------------------------------------------------------------------- 1 | # Beyond Good & Evil - *.mtx 2 | 3 | get mtx_name basename 4 | 5 | get mtx_id long 6 | if mtx_id != 0x2078746d # "mtx " 7 | cleanexit 8 | endif 9 | get mtx_01 long 10 | get mtx_size long 11 | get mtx_ipu_chunk_size long 12 | get mtx_ipu_size long 13 | get mtx_audio_interleave long 14 | get mtx_audio_channels long 15 | get mtx_audio_size long 16 | get mtx_sample_rate long 17 | get mtx_float_value long 18 | math mtx_init_offset = 0x28 19 | math mtx_chunk_offset = mtx_init_offset 20 | xmath mtx_audio_chunk_size "mtx_audio_interleave * mtx_audio_channels" 21 | xmath mtx_chunks "(mtx_size - 0x28) / (mtx_audio_chunk_size + mtx_ipu_chunk_size)" 22 | xmath last_chunk "mtx_chunks - 1" 23 | math mtx_skip_01 = mtx_audio_chunk_size 24 | math mtx_skip_02 = mtx_ipu_chunk_size 25 | xmath mtx_vag_remnants "mtx_audio_size * mtx_audio_channels" 26 | math mtx_ipu_remnants = mtx_ipu_size 27 | append 28 | for i = 0 < mtx_chunks 29 | goto mtx_chunk_offset 30 | string vag_name p "%s.vag" mtx_name 31 | if i == last_chunk 32 | math mtx_audio_chunk_size = mtx_vag_remnants 33 | endif 34 | log vag_name mtx_chunk_offset mtx_audio_chunk_size 35 | math mtx_chunk_offset + mtx_skip_01 36 | math mtx_vag_remnants - mtx_audio_chunk_size 37 | string ipu_name p "%s.ipu" mtx_name 38 | if i != 0 39 | if i == last_chunk 40 | math mtx_ipu_chunk_size = mtx_ipu_remnants 41 | endif 42 | log ipu_name mtx_chunk_offset mtx_ipu_chunk_size 43 | math mtx_ipu_remnants - mtx_ipu_chunk_size 44 | endif 45 | math mtx_chunk_offset + mtx_skip_02 46 | next i 47 | append 48 | -------------------------------------------------------------------------------- /bigbag_dat.bms: -------------------------------------------------------------------------------- 1 | # Brian Lara International Cricket 2007 (PS2) - BIGBAG.DAT 2 | 3 | get name filename 4 | if name == "BIGBAG.DAT" 5 | endian little 6 | goto 0 7 | get bbd_size long 8 | get bbd_info_file long 9 | get bbd_files long 10 | goto 0x20 11 | getdstring bbd_04 0x40 12 | getdstring bbd_build_date 0x10 13 | getdstring bbd_build_time 0x10 14 | goto 0xa0 15 | for i = 0 < bbd_files 16 | get file_01 long 17 | get file_offset long 18 | get file_size long 19 | get file_04 long 20 | getdstring file_name 0x40 21 | log file_name file_offset file_size 22 | next i 23 | else 24 | cleanexit 25 | endif 26 | -------------------------------------------------------------------------------- /chainall_toc_cin.bms: -------------------------------------------------------------------------------- 1 | # Code Age Commanders ~Tsugumono Tsugarerumono~ [1] (PS2) - chainall.[toc/cin] 2 | # --- 3 | # [1] close translation (from Japanese to English) for this title is Code Age Commanders ~Taking Over From Our People~ 4 | 5 | open FDDE "toc" 0 6 | open FDDE "cin" 1 7 | 8 | idstring 0 "CHAINTC2" 9 | get toc_size long 10 | math toc_pos = 12 11 | set full_name_01 string "" 12 | set full_name_02 string "" 13 | set directory_name string "" 14 | set file_name string "" 15 | math first_file_incoming = 0 16 | for toc_pos = toc_pos < toc_size 17 | goto toc_pos 18 | get control_code byte 19 | xmath info_type "control_code & 0x0f" 20 | xmath info_structure "(control_code >> 4) & 0x0f" 21 | if control_code != 0x45 22 | get control_size byte 23 | if info_structure = 4 24 | if info_type = 7 25 | xmath string_size "control_size - 8" 26 | elif info_type = 8 27 | xmath string_size "control_size - 7" 28 | endif 29 | elif info_structure = 6 30 | if info_type = 7 31 | xmath string_size "control_size - 7" 32 | elif info_type = 8 33 | xmath string_size "control_size - 6" 34 | endif 35 | endif 36 | if info_type = 4 37 | get directory_01 short 38 | get previous_directory_string_location byte 39 | get directory_keyword string 40 | set full_name_03 string "" 41 | for xp = 0 < previous_directory_string_location 42 | getvarchr string_char full_name_02 xp byte 43 | string string_char = string_char 44 | string full_name_03 + string_char 45 | next xp 46 | if previous_directory_string_location = 0 47 | string full_name_01 = directory_keyword 48 | string full_name_02 = full_name_01 49 | string full_name_03 = full_name_02 50 | else 51 | string full_name_03 + directory_keyword 52 | string full_name_02 = full_name_03 53 | endif 54 | string directory_name = full_name_03 55 | math first_file_incoming = 1 56 | else 57 | if info_type = 6 58 | get file_size long 59 | elif info_type = 7 60 | get file_size threebyte 61 | elif info_type = 8 62 | get file_size short 63 | endif 64 | if info_structure = 4 65 | get file_offset threebyte 66 | elif info_structure = 6 67 | get file_offset short 68 | endif 69 | if first_file_incoming != 1 70 | set full_name_04 string "" 71 | math string_size - 1 72 | get file_name_control_flags byte 73 | xmath upper_string_size "(file_name_control_flags >> 4) & 0x0f" 74 | xmath lower_string_size "file_name_control_flags & 0x0f" 75 | getdstring current_string string_size 76 | for xz1 = 0 < upper_string_size 77 | getvarchr string_char string_initials xz1 byte 78 | string string_char = string_char 79 | string full_name_04 + string_char 80 | next xz1 81 | string full_name_04 + current_string 82 | for xz1 = 0 < lower_string_size 83 | getvarchr string_char string_initials xz2 byte 84 | math xz2 - 1 85 | next xz1 86 | math xz3 = xz2 87 | for xz1 = 0 < lower_string_size 88 | getvarchr string_char string_initials xz3 byte 89 | math xz3 + 1 90 | string string_char = string_char 91 | string full_name_04 + string_char 92 | next xz1 93 | string string_initials = full_name_04 94 | strlen xz2 string_initials 1 95 | string file_name = string_initials 96 | else 97 | getdstring string_initials string_size 98 | math xz2 = string_size 99 | math xz2 - 1 100 | math first_file_incoming = 0 101 | string file_name = string_initials 102 | endif 103 | string r_name p "%s\%s" directory_name file_name 104 | math file_offset << 11 105 | log r_name file_offset file_size 1 106 | endif 107 | else 108 | math control_size = 1 109 | endif 110 | math toc_pos + control_size 111 | next 112 | -------------------------------------------------------------------------------- /chase_the_express_dpf.bms: -------------------------------------------------------------------------------- 1 | # Chase the Express/Covert Ops: Nuclear Dawn (PS1) - *.DPF 2 | 3 | idstring "PAK\x00" 4 | get dpf_files long 5 | for i = 0 < dpf_files 6 | get file_offset long 7 | get file_size long 8 | log "" file_offset file_size 9 | next i 10 | -------------------------------------------------------------------------------- /cing_fif_fpk.bms: -------------------------------------------------------------------------------- 1 | # Cing - *.[FIF+FPK] 2 | # --- 3 | # Garasu no Bara/Glass Rose (PS2) 4 | 5 | get ext extension 6 | if ext == "FIF" 7 | math fif1 = 0 8 | math fpk1 = 1 9 | elif ext == "FPK" 10 | math fif1 = 1 11 | math fpk1 = 0 12 | else 13 | cleanexit 14 | endif 15 | 16 | callfunction extract 1 17 | 18 | startfunction extract 19 | open FDDE "FIF" fif1 20 | open FDDE "FPK" fpk1 21 | get fif_size asize fif1 22 | xmath files "fif_size / 0x18" 23 | for i = 0 < files 24 | getdstring file_name 16 fif1 25 | get file_offset long fif1 26 | math file_offset << 11 27 | get file_size long fif1 28 | if file_name != "" 29 | log file_name file_offset file_size fpk1 30 | endif 31 | next i 32 | endfunction 33 | -------------------------------------------------------------------------------- /dark_cloud.bms: -------------------------------------------------------------------------------- 1 | # Level-5 games / Dark Cloud (2021/10/08) 2 | # original script by aluigi, modified by RetingencyPlan 3 | # --- 4 | # in every Level-5 game on the PS2, there was this 5 | # self-contained archvial file whose format 6 | # kinda changed across many of their releases. 7 | 8 | get EXT extension 9 | 10 | if EXT == "HED" 11 | # Dark Cloud (PS2) - strangely enough, data.hed comes from the full USA release of the game 12 | open FDDE "DAT" 1 13 | get hed_size asize # necessary because of how simple this format is, later HD# formats put a delimiter of sorts to tell the game that there's no files to read beyond that point. 14 | xmath files "hed_size / 0x50" # calculate the number of files through the hed_size value 15 | for i = 0 < files 16 | getdstring file_name 0x40 # garbage leaks everywhere 17 | get file_offset long 18 | get file_size long 19 | get file_offset_in_cdvd_sectors long 20 | math file_offset_in_cdvd_sectors << 11 21 | if file_offset != file_offset_in_cdvd_sectors 22 | break 23 | endif 24 | get file_size_in_cdvd_sectors long 25 | math file_size_in_cdvd_sectors << 11 26 | callfunction check_file_size 1 27 | log file_name file_offset file_size 1 28 | next i 29 | elif EXT == "HD2" 30 | # Dark Cloud (PS2) - data.hd2, used elsewhere including the aforementioned USA release 31 | open FDDE "DAT" 1 32 | for 33 | get name_offset long 34 | savepos temp_01 35 | goto name_offset 36 | get file_name string 37 | if file_name == "" # when i said "delimiter of sorts" i meant EXACTLY that, if the file_name value contains literally nothing, that's it. 38 | break 39 | endif 40 | goto temp_01 41 | get hd2_02 long # always 0 42 | if hd2_02 != 0 43 | break 44 | endif 45 | get hd2_03 long # ditto 46 | if hd2_03 != 0 47 | break 48 | endif 49 | get hd2_04 long # ditto 50 | if hd2_04 != 0 51 | break 52 | endif 53 | get file_offset long 54 | get file_size long 55 | get file_offset_in_cdvd_sectors long 56 | math file_offset_in_cdvd_sectors << 11 57 | if file_offset != file_offset_in_cdvd_sectors 58 | break 59 | endif 60 | get file_size_in_cdvd_sectors long 61 | math file_size_in_cdvd_sectors << 11 62 | callfunction check_file_size 1 63 | log file_name file_offset file_size 1 64 | next 65 | elif EXT == "HD3" 66 | # Dark Chronicle/Dark Cloud 2 (PS2) 67 | open FDDE "DAT" 1 68 | for 69 | get name_offset long 70 | savepos temp_01 71 | goto name_offset 72 | get file_name string 73 | if file_name == "" 74 | break 75 | endif 76 | goto temp_01 77 | get file_size long 78 | get file_offset long 79 | math file_offset << 11 80 | get file_size_in_cdvd_sectors long 81 | math file_size_in_cdvd_sectors << 11 82 | callfunction check_file_size 1 83 | log file_name file_offset file_size 1 84 | next 85 | elif EXT == "HD4" 86 | # Dark Chronicle/Dark Cloud 2 (PS2) 87 | open FDDE "DAT" 1 88 | for 89 | get name_offset long 90 | savepos temp_01 91 | goto name_offset 92 | get file_name string 93 | if file_name == "" 94 | break 95 | endif 96 | goto temp_01 97 | get file_size long 98 | get file_offset long 99 | math file_offset << 11 100 | log file_name file_offset file_size 1 101 | next 102 | elif EXT == "HD5" 103 | # Dragon Quest VIII Premium Eizou Disc (SLPM-62490) 104 | open FDDE "DAT" 1 105 | for 106 | get name_offset long 107 | savepos temp_01 108 | goto name_offset 109 | get file_name string 110 | goto temp_01 111 | if file_name == "" 112 | break 113 | endif 114 | get file_02 long # always 0 115 | if file_02 != 0 116 | break 117 | endif 118 | get file_size_01 long 119 | get file_size_02 long 120 | get file_offset long 121 | math file_offset << 11 122 | if file_size_01 != file_size_02 123 | break 124 | endif 125 | log file_name file_offset file_size_01 1 126 | next 127 | elif EXT == "HD6" 128 | # Dragon Quest VIII (PS2) 129 | # Rogue Galaxy (PS2) 130 | open FDDE "DAT" 1 131 | idstring "HD6\0" 132 | get keyword_info_offset long 133 | get keyword_info_size long 134 | get total_keywords long 135 | get hd6_04 long 136 | if hd6_04 != 0 137 | break 138 | endif 139 | get keyword_fetch_offset long 140 | get keyword_fetch_size long 141 | get hd6_07 long 142 | if hd6_07 != 0 143 | break 144 | endif 145 | get block_size_per_file long 146 | get files long 147 | get file_info_offset long 148 | get hd6_11 long 149 | if hd6_11 != 0 150 | break 151 | endif 152 | get hd6_size long 153 | goto keyword_info_offset 154 | for a = 0 < total_keywords 155 | get keyword string 156 | putarray 0 a keyword 157 | next a 158 | goto file_info_offset 159 | for i = 0 < files 160 | # HD6 structure has a bug in which the last actual file gets repeated twice. 161 | #getdstring hd6_file_info 8 162 | getbits name_offset 18 163 | math name_offset + keyword_fetch_offset 164 | savepos temp_01 165 | goto name_offset 166 | set file_name string "" 167 | do 168 | get keyword_number variable4 169 | getarray keyword 0 keyword_number 170 | string file_name + keyword 171 | while keyword_number != 0 172 | goto temp_01 173 | if file_name == "" 174 | break 175 | endif 176 | getbits file_offset 22 177 | math file_offset << 11 178 | getbits file_size 24 179 | math file_size * block_size_per_file 180 | log file_name file_offset file_size 1 181 | next i 182 | else 183 | print " this script can only work with .hed/.hd2/.hd3/.hd4/.hd5/.hd6 files at this point. " 184 | cleanexit 185 | endif 186 | 187 | startfunction check_file_size 188 | # what this function does is it compares one file size value to another 189 | # with the DVD block size number as a basis to do the comparison from. 190 | # although, given that the game streams everything from disk 191 | # this is simply here for information sake. 192 | xmath modulus1 "2048 - (file_size_in_cdvd_sectors % 2048)" 193 | xmath modulus2 "2048 - (file_size % 2048)" 194 | if modulus1 == modulus2 195 | print " file size is aligned to a multiple of 2048 (DVD sector size) " 196 | else 197 | string wv1 p "%s blank spaces" modulus2 198 | print " file size is short of %wv1% " 199 | endif 200 | endfunction 201 | -------------------------------------------------------------------------------- /darkest_of_days.bms: -------------------------------------------------------------------------------- 1 | # Darkest of Days 2 | 3 | get name filename 4 | get ext extension 5 | 6 | if ext == "cage" 7 | comtype zlib_noerror 8 | get cage_size asize 9 | math cage_offset = 0 10 | for i = 0 11 | goto cage_offset 12 | if cage_offset >= cage_size 13 | print " this script has reached through the tail end of %name%. " 14 | cleanexit 15 | endif 16 | get file_name string 17 | get original_file_size long 18 | get compressed_file_size long 19 | savepos cage_offset 20 | math chunk_offset_within_file = cage_offset 21 | append 22 | for j = 0 < compressed_file_size 23 | math skip_this_chunk = 0 24 | goto chunk_offset_within_file 25 | get original_chunk_size long 26 | get compressed_chunk_size long 27 | math chunk_offset_within_file + 8 28 | if original_chunk_size == 0x10 29 | if compressed_chunk_size == 0x13 30 | math skip_this_chunk = 1 31 | endif 32 | endif 33 | if skip_this_chunk = 0 34 | clog file_name chunk_offset_within_file compressed_chunk_size original_chunk_size 35 | endif 36 | math j + 8 37 | math chunk_offset_within_file + compressed_chunk_size 38 | math j + compressed_chunk_size 39 | next 40 | append 41 | math cage_offset + compressed_file_size 42 | next i 43 | endif 44 | -------------------------------------------------------------------------------- /doom_3_bfg_edition.bms: -------------------------------------------------------------------------------- 1 | # DOOM 3 BFG Edition (Windows[1], PlayStation 3, Xbox 360, Android, PlayStation 4[2], Xbox One[2], Nintendo Switch[2]) 2 | # DOOM 3: VR Edition (PlayStation 4[3]) 3 | # --- 4 | # [1] this was re-released as DOOM 3 through Bethesda.net Launcher in 2019. 5 | # [2] same case as [1], only this time targeted at different platforms. 6 | # however, functionality with these versions of the game won't be guaranteed with this script 7 | # so if i were you i'd open up an issue about it *fast* the moment i find out 8 | # that the script doesn't work with the game files when it comes to these versions. 9 | # [3] an PSVR adaptation of the BFG Edition game. 10 | 11 | get name basename 12 | get ext extension 13 | 14 | if ext == "resources" 15 | open FDDE "resources" 0 16 | elif ext == "obb" 17 | open FDDE "obb" 0 18 | endif 19 | open FDDE "crc" 1 EXISTS 20 | 21 | endian big 22 | 23 | get resources_sign long 0 24 | if resources_sign != 0xd000000d 25 | print " this is not a .resources file from DOOM 3 BFG Edition. " 26 | cleanexit 27 | endif 28 | get resources_info_offset long 0 29 | get resources_info_size long 0 30 | goto resources_info_offset 0 31 | get resources_files long 0 32 | if EXISTS = 1 33 | get crc_sign_01 long 1 34 | if crc_sign_01 != 0xcc00cc00 35 | print " this is not a .crc file from DOOM 3 BFG Edition. " 36 | cleanexit 37 | endif 38 | get crc_sign_02 long 1 39 | if crc_sign_02 != 1 40 | print " this is not a .crc file from DOOM 3 BFG Edition. " 41 | cleanexit 42 | endif 43 | get crc_name_hash long 1 44 | get crc_files long 1 45 | if resources_files == crc_files 46 | math files == crc_files 47 | endif 48 | endif 49 | math files = resources_files 50 | for i = 0 < files 51 | get file_01 long 0 52 | xmath file_name_string_size "((file_01 & 0x000000ff) << 24) | ((file_01 & 0x0000ff00) << 8) | ((file_01 & 0x00ff0000) >> 8) | ((file_01 & 0xff000000) >> 24)" 53 | getdstring file_name file_name_string_size 0 54 | get file_offset long 0 55 | get file_size long 0 56 | if EXISTS = 1 57 | get file_name_hash long 1 58 | endif 59 | log file_name file_offset file_size 0 60 | next i 61 | -------------------------------------------------------------------------------- /driving_emotion_type-s.bms: -------------------------------------------------------------------------------- 1 | # Driving Emotion Type-S (PS2) - LINKFILE.INF/BIN 2 | 3 | open FDDE "inf" 0 4 | open FDDE "bin" 1 5 | 6 | idstring 0 "NTBL" 7 | idstring 1 "JOIN" 8 | get ntbl_files long 0 9 | get join_files long 1 10 | if ntbl_files == join_files 11 | math total_files == join_files 12 | else 13 | print "\n number of files as listed in NTBL header - %ntbl_files% \n number of files as listed in JOIN header - %join_files% \n \n these numbers can't mesh at all with each other, so from now on don't expect any miracles " 14 | break 15 | endif 16 | 17 | for i = 0 < total_files 18 | get name_offset long 0 19 | savepos temp_01 0 20 | goto name_offset long 0 21 | get file_name string 0 22 | goto temp_01 0 23 | get file_offset long 1 24 | math file_offset << 11 25 | get file_size long 1 26 | 27 | if file_size && 0x10000000 28 | # this kind of archive format makes various references to a lot of non-existent files 29 | print "%file_name%(%file_offset|x%) - presumed dead" 30 | else 31 | log file_name file_offset file_size 1 32 | endif 33 | next i 34 | -------------------------------------------------------------------------------- /dskimg_inf_bin.bms: -------------------------------------------------------------------------------- 1 | # Gacha Mecha Stadium Saru Battle/Ape Escape: Pumped & Primed - dskimg[.inf/.bin] 2 | # Saru! Get You! Million Monkeys - data0.bin/data1.bin, data2.bin/data3.bin 3 | 4 | comtype gzip 5 | 6 | get INF_BIN_BNAME basename 7 | 8 | if INF_BIN_BNAME == "dskimg" 9 | open FDDE "inf" 0 10 | open FDDE "bin" 1 11 | callfunction PARSE_INF 12 | elif INF_BIN_BNAME == "data0" || INF_BIN_BNAME == "data1" 13 | open FDSE "data0.bin" 0 14 | open FDSE "data1.bin" 1 15 | callfunction PARSE_INF 16 | elif INF_BIN_BNAME == "data2" || INF_BIN_BNAME == "data3" 17 | open FDSE "data2.bin" 0 18 | open FDSE "data3.bin" 1 19 | callfunction PARSE_INF 20 | endif 21 | 22 | startfunction PARSE_INF 23 | get INF_SIZE asize 0 24 | get DAT_SIZE asize 1 25 | xmath FILES "INF_SIZE / 12" 26 | 27 | for i = 0 < FILES 28 | get HASH long 29 | get OFFSET long 30 | get SIZE long 31 | 32 | math OFFSET << 11 33 | if OFFSET u>= DAT_SIZE 34 | break 35 | endif 36 | 37 | goto OFFSET 1 38 | get SIGN short 1 39 | if SIGN == 0x8b1f 40 | get GZIP_COMPRESSION_SIGN byte 1 41 | get GZIP_FLAGS byte 1 42 | get GZIP_UNIX_TIMESTAMP long 1 43 | if GZIP_COMPRESSION_SIGN == 8 44 | get GZIP_EXTRA_COMPRESSION_FLAGS byte 1 45 | endif 46 | get GZIP_OS_ORIGIN byte 1 47 | savepos GZIP_TMP1 1 48 | xmath GZIP_TMP2 "GZIP_TMP1 + (SIZE - 18)" # gzip uses deflate compression anyway 49 | goto GZIP_TMP2 1 50 | get GZIP_CRC32 long 1 51 | get GZIP_ZSIZE long 1 52 | string FNAME p "%08x_%08x." HASH GZIP_CRC32 53 | clog FNAME OFFSET SIZE GZIP_ZSIZE 1 54 | else 55 | string FNAME p "%08x." HASH 56 | if SIZE != 0 57 | log FNAME OFFSET SIZE 1 58 | endif 59 | endif 60 | next i 61 | endfunction 62 | -------------------------------------------------------------------------------- /dxmd_dxb_archive.bms: -------------------------------------------------------------------------------- 1 | # Deus Ex: Narrative Divided (PC, PS4, XBOXONE) 2 | # Deus Ex: Sixty-Hour Arcade Hacking Game (PC(Steam)) 3 | 4 | # sub_1400B0AA0 (DXB.exe) 5 | 6 | idstring "ARCH" 7 | get arch_initial_hash long 8 | get arch_total_files long 9 | get arch_archive_names long 10 | get arch_info_offset longlong 11 | 12 | goto arch_info_offset 13 | for i1 = 1 <= arch_archive_names 14 | callfunction get_string 1 15 | next i1 16 | 17 | for i2 = 1 <= arch_total_files 18 | get file_generation_date time64 19 | getdstring file_hash 16 20 | callfunction get_string 1 21 | get file_chunks long 22 | append 23 | for j1 = 1 <= file_chunks 24 | get chunk_info_01 long 25 | get chunk_position longlong 26 | get chunk_offset longlong 27 | get chunk_size longlong 28 | log asset_string chunk_offset chunk_size 29 | next j1 30 | append 31 | next i2 32 | 33 | startfunction get_string 34 | get asset_string_size long 35 | math asset_string_size + 1 36 | getdstring asset_string asset_string_size 37 | endfunction 38 | -------------------------------------------------------------------------------- /fbrb.bms: -------------------------------------------------------------------------------- 1 | # Frostbite Engine(2008-2010) - *.fbrb 2 | 3 | endian big 4 | 5 | get fbrb_size asize 6 | get fbrb_sign long 7 | if fbrb_sign != 0x46625242 8 | print " this is not an actual .fbrb file " 9 | cleanexit 10 | endif 11 | get fbrb_header_size long 12 | xmath base_offset "fbrb_header_size + 8" 13 | xmath base_size "fbrb_size - base_offset" 14 | get if_gzip short 15 | if if_gzip = 0x1f8b 16 | comtype gzip 17 | clog MEMORY_FILE 8 fbrb_header_size fbrb_header_size 18 | math file_number = -1 19 | else 20 | math file_number = 0 21 | endif 22 | goto base_offset 23 | get if_gzip_for_real short 24 | if if_gzip_for_real = 0x1f8b 25 | comtype gzip 26 | clog TEMPORARY_FILE base_offset base_size base_size 27 | else 28 | log TEMPORARY_FILE base_offset base_size 29 | endif 30 | get fbrb_version long file_number 31 | get fbrb_name_index_size long file_number 32 | xmath fbrb_file_info_offset "fbrb_name_index_size + 8" 33 | goto fbrb_file_info_offset file_number 34 | get fbrb_total_entries long file_number 35 | open "." TEMPORARY_FILE 1 36 | for i = 0 < fbrb_total_entries 37 | get name_string_offset long file_number 38 | if file_number = 0 39 | math name_string_offset + 16 40 | elif file_number = -1 41 | math name_string_offset + 8 42 | endif 43 | savepos fbrb_tmp_01 file_number 44 | goto name_string_offset file_number 45 | get file_name_string string file_number 46 | goto fbrb_tmp_01 file_number 47 | get fixed_chunk_size long file_number 48 | get file_offset long file_number 49 | get file_size_with_res_header long file_number 50 | get file_size_without_res_header long file_number 51 | get file_type long file_number 52 | log file_name_string file_offset file_size_with_res_header 1 53 | next i 54 | -------------------------------------------------------------------------------- /final_fantasy_xii.bms: -------------------------------------------------------------------------------- 1 | # Final Fantasy XII (PS2) 2 | 3 | goto 0xba000 4 | 5 | xmath base_sec_offset "0x174 << 11" 6 | get sec_sign long 7 | xmath is_sec "((sec_sign & 0xff) << 16) | (((sec_sign & 0xff00) >> 8) << 8) | ((sec_sign & 0xff0000) >> 16)" 8 | if is_sec != 0x736563 9 | cleanexit 10 | endif 11 | xmath sec_version "(sec_sign & 0xff000000) >> 24" 12 | get sec_entries short 13 | get sec_name string 14 | if sec_version = 0x67 15 | get secg_01 long 16 | endif 17 | for i = 0 <= sec_entries 18 | get loc_01 long 19 | putarray 1 i loc_01 20 | get loc_02 long 21 | putarray 2 i loc_02 22 | get fil_01 short 23 | putarray 3 i fil_01 24 | next i 25 | getarray last_file_offset_location_per_entry 2 0 26 | 27 | sortarray 1 1 28 | 29 | math base_file_offset = 0x1f4 30 | math tentative_offset_01 = 0 31 | for i = 0 <= sec_entries 32 | getarray file_offset_location_per_entry 1 i 33 | if file_offset_location_per_entry != 0 34 | math i + 1 35 | if i == 0x25 36 | math next_file_offset_location_per_entry = last_file_offset_location_per_entry 37 | else 38 | getarray next_file_offset_location_per_entry 1 i 39 | endif 40 | math i - 1 41 | xmath file_offset_entries "(next_file_offset_location_per_entry - file_offset_location_per_entry) / 3" 42 | math file_offset_location_per_entry + base_sec_offset 43 | for j1 = 0 < file_offset_entries 44 | goto file_offset_location_per_entry 45 | math tb4 = 0 46 | for tb1 = 0 < 3 47 | get tb2 byte 48 | xmath tb3 "tb1 * 8" 49 | xmath tb4 "tb4 | tb2 << tb3" 50 | next tb1 51 | putarray 11 j1 tb4 52 | math file_offset_location_per_entry + 3 53 | next j1 54 | endif 55 | getarray file_size_location_per_entry 2 i 56 | math file_size_location_per_entry + base_sec_offset 57 | getarray total_number_of_files_per_entry 3 i 58 | if file_size_location_per_entry != 0 59 | goto file_size_location_per_entry 60 | for j2 = 0 < total_number_of_files_per_entry 61 | get c3e long 62 | putarray 12 j2 c3e 63 | next j2 64 | endif 65 | if total_number_of_files_per_entry != 0 66 | math k2 = 0 67 | math add_01 = 0 68 | for j = 0 < total_number_of_files_per_entry 69 | xmath is "i + 1" 70 | xmath js "j + 1" 71 | string temp_name p "%s/%04d/%04d." sec_name is js 72 | getarray file_size 12 j 73 | xmath normal_file_size "(file_size >> 2) & 0x3fffffff" 74 | xmath ashe_compressed_file_size "(file_size >> 1) & 0x7ff" 75 | xmath ashe_original_file_size "(file_size >> 8) & 0xffffff" 76 | for k1 = k2 < file_offset_entries 77 | getarray file_offset 11 k1 78 | xmath normal_file_offset "(file_offset >> 2) & 0x3fffff" 79 | if j = 0 80 | if k1 = 0 81 | math tentative_offset_01 = normal_file_offset 82 | endif 83 | endif 84 | if normal_file_size != 0x3fffffff 85 | if normal_file_offset == tentative_offset_01 86 | math k4 = k1 87 | xmath k5 "k4 + 1" 88 | for k3 = k4 < k5 89 | if k3 == file_offset_entries 90 | break 91 | endif 92 | getarray next_file_offset 11 k3 93 | math next_file_offset >> 2 94 | math next_file_offset & 0x3fffff 95 | if next_file_offset == normal_file_offset 96 | math k3 + 1 97 | math k5 + 1 98 | else 99 | math k4 = k2 100 | break 101 | endif 102 | next k5 103 | else 104 | math k2 = k1 105 | break 106 | endif 107 | else 108 | math k2 = k1 109 | break 110 | endif 111 | next k1 112 | xmath real_file_offset "(tentative_offset_01 << 11) + (base_file_offset << 11)" 113 | goto real_file_offset 114 | get is_ashe long 115 | if normal_file_size != 0x3fffffff 116 | if is_ashe == 0x65687361 117 | get ashe_01 long 118 | get ashe_02 long 119 | get ashe_03 long 120 | xmath temp_size "ashe_compressed_file_size << 11" 121 | log temp_name real_file_offset temp_size 122 | math add_01 = ashe_compressed_file_size 123 | else 124 | log temp_name real_file_offset normal_file_size 125 | xmath modulus_01 "normal_file_size % (1 << 11)" 126 | if modulus_01 = 0 127 | xmath add_01 "normal_file_size >> 11" 128 | else 129 | xmath add_01 "(normal_file_size >> 11) + 1" 130 | endif 131 | endif 132 | else 133 | math add_01 = 0 134 | endif 135 | math tentative_offset_01 + add_01 136 | math file_size_location_per_entry + 4 137 | next j 138 | endif 139 | next i 140 | -------------------------------------------------------------------------------- /frequency_ark.bms: -------------------------------------------------------------------------------- 1 | # Frequency - *.ARK 2 | 3 | open FDDE "ark" 0 4 | 5 | comtype gzip 6 | 7 | get sig long 8 | if sig != 0x004b5241 9 | cleanexit 10 | endif 11 | get version long 12 | get dirOffset long 13 | get numFiles long 14 | get relPathOffset long 15 | get numPaths long 16 | get stringTabOffset long 17 | get numStrings long 18 | get sizeHdrAndDir long 19 | get sectorSize long 20 | 21 | goto 0x40 22 | get path string 23 | 24 | goto dirOffset 25 | for i1 = 0 < numFiles 26 | get a01 long 27 | putarray 1 i1 a01 28 | get a02 long 29 | putarray 2 i1 a02 30 | get a03 short 31 | putarray 3 i1 a03 32 | get a04 short 33 | putarray 4 i1 a04 34 | get a05 long 35 | putarray 5 i1 a05 36 | get a06 long 37 | putarray 6 i1 a06 38 | get a07 long 39 | putarray 7 i1 a07 40 | next i1 41 | goto relPathOffset 42 | for i2 = 0 < numPaths 43 | get b01 long 44 | putarray 8 i2 b01 45 | get b02 long 46 | putarray 9 i2 b02 47 | next i2 48 | goto stringTabOffset 49 | for i3 = 0 < numStrings 50 | get c0 string 51 | putarray 10 i3 c01 52 | next i3 53 | 54 | for z = 0 < numFiles 55 | set file_name string "" 56 | getarray nameHash 1 z 57 | getarray nameOffset 2 z 58 | goto nameOffset 59 | get name string 60 | getarray relPathIndex 3 z 61 | getarray pathHash 8 relPathIndex 62 | getarray pathOffset 9 relPathIndex 63 | goto pathOffset 64 | get path string 65 | getarray sectorOffset 4 z 66 | getarray sector 5 z 67 | xmath file_offset "(sector << 11) + sectorOffset" 68 | getarray length_if_normal_file 6 z 69 | getarray length_if_gzip_file 7 z 70 | string file_name p "%s/%s" path name 71 | if length_if_normal_file == length_if_gzip_file 72 | log file_name file_offset length_if_normal_file 73 | else 74 | set file_name_without_the_gz string file_name 75 | string file_name_without_the_gz > ".gz" 76 | clog file_name_without_the_gz file_offset length_if_normal_file length_if_gzip_file 77 | endif 78 | next z 79 | -------------------------------------------------------------------------------- /front_mission_ps2_pos_dat.bms: -------------------------------------------------------------------------------- 1 | # dvdimage.pos/dvdimage.dat 2 | # --- 3 | # Front Mission 4 (PS2) 4 | # Front Mission Online (PS2) 5 | # Front Mission 5 (PS2) 6 | 7 | open FDDE "pos" 0 8 | open FDDE "dat" 1 9 | 10 | get pos_entries long 11 | xmath pos_info_offset "(pos_entries * 4) + 8" 12 | for i = 0 < pos_entries 13 | get pos_entry_id short 14 | get pos_entry_entries short 15 | savepos tmp_01 16 | goto pos_info_offset 17 | for j = 0 < pos_entry_entries 18 | get file_offset long 19 | math file_offset << 11 20 | get file_size long 21 | xmath i2 "i + 1" 22 | xmath j2 "j + 1" 23 | string temp_name p "%03d_%05d/%05d." i2 pos_entry_id j2 24 | log temp_name file_offset file_size 1 25 | math pos_info_offset + 8 26 | next j 27 | goto tmp_01 28 | next i 29 | -------------------------------------------------------------------------------- /gear_bigfile.bms: -------------------------------------------------------------------------------- 1 | # [ GEAR BigFile ] - *.bf/*.big/*.bin 2 | # --- 3 | # Rocky Balboa (PlayStation Portable) 4 | # Shaun White Snowboarding (PlayStation Portable) - SOUNDSTREAMS_PSP.BIN 5 | # Shaun White Snowboarding: Road Trip (Wii) - SoundStreams_WII.bin 6 | 7 | idstring "[ GEAR BigFile ]" 8 | get gear_01 long 9 | get gear_02 long 10 | get files long 11 | get gear_04 long 12 | math gear_off_01 = 0x20 13 | goto gear_off_01 14 | for i = 0 < files 15 | get entry_01 longlong 16 | putarray 0 i entry_01 17 | next i 18 | for i = 0 < files 19 | get entry_02 long 20 | putarray 1 i entry_02 21 | next i 22 | for i = 0 < files 23 | get entry_03 long 24 | putarray 2 i entry_03 25 | next i 26 | for i = 0 < files 27 | getarray file_offset 0 i 28 | getarray file_size 1 i 29 | getarray hardcoded_name_hash 2 i 30 | string temp_name p "%u." hardcoded_name_hash 31 | log temp_name file_offset file_size 32 | next i 33 | -------------------------------------------------------------------------------- /gnfs.bms: -------------------------------------------------------------------------------- 1 | get flags long 2 | xmath sign "flags & 0xff" 3 | if sign != 0xd0 4 | cleanexit 5 | endif 6 | xmath entries "(flags >> 8) & 0xff" 7 | callfunction get_string 1 8 | set fn1 string asset_string 9 | for i = 0 < entries 10 | get file_info long 11 | xmath remaining_bytes "file_info & 0x7ff" 12 | putarray 0 i remaining_bytes 13 | xmath file_offset "file_info & 0xfffff800" 14 | putarray 1 i file_offset 15 | next i 16 | get full_size long 17 | getarray info_off2 1 0 18 | goto info_off2 19 | getdstring dummy 0x20 20 | xmath files "entries - 1" 21 | math a1 = 1 22 | for i = 0 < files 23 | getarray fo1 1 a1 24 | callfunction get_string 1 25 | set fn2 string asset_string 26 | getdstring file_info 0x20 27 | getvarchr fs1 file_info 0 long 28 | getvarchr fs2 file_info 8 long 29 | if fs1 == fs2 30 | log fn2 fo1 fs1 31 | else 32 | print " file is compressed " 33 | endif 34 | math a1 + 1 35 | next i 36 | 37 | startfunction get_string 38 | get asset_string string 39 | padding 4 40 | endfunction 41 | -------------------------------------------------------------------------------- /god-of-war-ii_ps2_toc.bms: -------------------------------------------------------------------------------- 1 | # GOD OF WAR II (PS2) - godofwar.toc 2 | # --- 3 | # different (if not evolved) TOC format from godofwar.toc from GOD OF WAR 2005, to the point they're barely identical from each other. 4 | # there is now a file count at the start of the format, followed by proper TOC which contains the following: 5 | # the TOC is now divided into two parts - one containing file name field and other stuff, and the other where it's nothing but file name fields. 6 | # there is now a file count at the start of the format, and it actually accounts for the former. 7 | # as for the first part itself, there are four fields that contain the following. 8 | # an expanded file name field, file size field, some field telling how many times the file is stored in the paks (seriously!) and an file offset index field. 9 | # the file duplicate thing in particular influences how the second part works, and the index field is just a pointer for what contains the following. 10 | # the second part contains nothing but file offset fields. in fact it's how the index field from the first part exists in the first place. 11 | # the index field itself serves as a look up for the file offset fields, this way said offset value gets obtained rather easily. 12 | # that said, there can be dozens of file offset fields holding the same file in different parts of two pak files, meaning even file duplicates are present there as well. 13 | # as for the file offset value itself, it's obtained through an if-else condition where 14 | # if a certain number is high enough, said number must be added through another number, like this: 15 | # if 10007466 > 9999999 then 10007466 + (-10000000) = 7466. 16 | # much of the info has been gathered through smpd.irx. 17 | 18 | get name1 filename 19 | if name1 != "godofwar.toc" 20 | cleanexit 21 | endif 22 | 23 | goto 0 24 | get files long 25 | math pos1 = 4 26 | xmath pos2 "pos1 + (files * 0x24)" 27 | set file_offset_threshold long 0x98967f 28 | set file_offset_seed long 0xff676980 29 | math part_number = 0 30 | for i = 0 < files 31 | goto pos1 32 | getdstring file_name 24 33 | get file_size long 34 | get file_duplicates long 35 | get file_offset_index long 36 | math file_offset_index * 4 37 | math file_offset_index + pos2 38 | for i1 = 0 < file_duplicates 39 | # extracting the same file as many times as the file_duplicates value dictates 40 | goto file_offset_index 41 | get file_offset long 42 | # in case file_offset value passes a certain threshold. 43 | # setting part_number here is also important as the script would just not work without it. 44 | if file_offset > file_offset_threshold 45 | math file_offset + file_offset_seed 46 | math part_number = 2 47 | else 48 | math part_number = 1 49 | endif 50 | math file_offset << 11 51 | math file_offset & 0xffffffff 52 | # ^ here to accomodate quickbms_4gb_files usage, quickbms works fine without it. 53 | # but if left unchecked, quickbms_4gb_files could throw out an error saying it could not reach this offset within an loaded pak file. 54 | # and given how pak files are usually 3.96GB this was a necessity. 55 | callfunction extract_file 1 56 | math file_offset_index + 4 57 | next i1 58 | math pos1 + 36 59 | next i 60 | 61 | startfunction extract_file 62 | # pak loading feature inherited from the TOC format of GOD OF WAR 2005. 63 | # as said in that script, the devs had to find a way to ensure the game 64 | # laoded any file it wanted to load within an DVD9 disc, hence 65 | # why we have part1.pak and part2.pak, respectively. 66 | # the script streamlines this pak loading process. 67 | string part_name p "part%u.pak" part_number 68 | open FDSE part_name 1 69 | log file_name file_offset file_size 1 70 | endfunction 71 | -------------------------------------------------------------------------------- /god-of-war_ps2_toc.bms: -------------------------------------------------------------------------------- 1 | # GOD OF WAR (PS2) - godofwar.toc 2 | # --- 3 | # TOC format itself is pretty simple. contains a TOC which has only file name, part number, file size and file offset fields. 4 | # if file name field is empty (usually near the end of the file), that's it. that means no more files left for this TOC. 5 | # of course, it can also store the same file 7 times in a row, and the pak files account for this as well. 6 | # given how simple the format is, the script does not (and cannot) account for that in any way. 7 | 8 | get name1 filename 9 | if name1 != "godofwar.toc" 10 | cleanexit 11 | endif 12 | 13 | for i = 0 14 | getdstring file_name 12 15 | if file_name == "" 16 | # a null delimiter so the game can say "stop" when it finds out it has no more files to dig into memory 17 | # (either by streaming stuff into memory or just loading the whole thing straight into it, which rarely happens) 18 | print " no more files left " 19 | break 20 | endif 21 | get part_number long 22 | math part_number + 1 23 | get file_size long 24 | get file_offset long 25 | math file_offset << 11 26 | callfunction extract_file 1 27 | next i 28 | 29 | startfunction extract_file 30 | # the TOC format uses two pak files - part1.pak and part2.pak 31 | # the game loads those two files depending on where the file is at. 32 | # as GOD OF WAR 2005 is a DVD9 game the devs had make sure all data is loaded 33 | # anywhere the game wants within the disc, hence these two files. 34 | # pak loading is streamlined here for simplicity sake. 35 | string part_name p "part%u.pak" part_number 36 | open FDSE part_name 1 37 | log file_name file_offset file_size 1 38 | endfunction 39 | -------------------------------------------------------------------------------- /god_of_war_wad.bms: -------------------------------------------------------------------------------- 1 | # God of War/God of War 2 (PS2) - *.WAD 2 | 3 | open FDDE "wad" 0 4 | 5 | get wad_size asize 0 6 | savepos offset 7 | do 8 | goto offset 9 | get type long 10 | get size long 11 | getdstring name 0x18 12 | savepos offset 13 | if type == 0x18 14 | math size == 0 15 | endif 16 | if size != 0 17 | log name offset size 18 | endif 19 | math offset += size 20 | math offset x= 0x10 21 | while offset < wad_size 22 | -------------------------------------------------------------------------------- /gran_turismo_2.bms: -------------------------------------------------------------------------------- 1 | # Gran Turismo 2 2 | # GT2.VOL, GT2.OVL 3 | 4 | get polyphony_archivename basename 5 | get polyphony_archivextension extension 6 | 7 | if polyphony_archivename == "GT2" 8 | if polyphony_archivextension == "VOL" 9 | get vol_sign long 10 | if vol_sign != 0x53465447 # GTFS 11 | print " not a GTFS(GT2.VOL) file, contact me if you want me to take a look at your file. " 12 | cleanexit 13 | endif 14 | get zero_01 long 15 | get individual_entries short 16 | get overall_entries short 17 | get zero_02 long 18 | for i = 0 < individual_entries 19 | get entry_value long 20 | xmath remaining_bytes_for_entry "entry_value & 0x7ff" 21 | putarray 1 i remaining_bytes_for_entry 22 | xmath entry_offset "(entry_value >> 11) & 0x1fffff" 23 | putarray 2 i entry_offset 24 | next i 25 | 26 | getarray overall_entry_info_offset 2 1 27 | math overall_entry_info_offset << 11 28 | goto overall_entry_info_offset 29 | for i = 0 < overall_entries 30 | get file_timestamp time 31 | putarray 3 i file_timestamp 32 | get entry_info_index short 33 | putarray 4 i entry_info_index 34 | get entry_flag byte 35 | xmath last_entry "(entry_flag >> 7) & 1" 36 | putarray 5 i last_entry 37 | xmath entry_type "entry_flag & 1" 38 | putarray 6 i entry_type 39 | getdstring entry_name 0x19 40 | putarray 7 i entry_name 41 | next i 42 | 43 | for directory = 0 < 256 44 | putarray 101 j 0 45 | putarray 102 j 0 46 | putarray 103 j "" 47 | next directory 48 | math current_entry = 0 49 | math previous_entry = 0 50 | math current_directory = 0 51 | math all_parsed_entries = 0 52 | xmath last_entry "overall_entries - 1" 53 | callfunction parse_gtfs 1 54 | 55 | startfunction parse_gtfs 56 | for i = current_entry < overall_entries 57 | putarray 101 current_directory current_entry 58 | xmath next_entry "current_entry + 1" 59 | putarray 102 current_directory next_entry 60 | getarray file_timestamp 3 i 61 | getarray entry_info_index 4 i 62 | getarray entry_dead_end 5 i 63 | getarray entry_type 6 i 64 | getarray entry_name 7 i 65 | putarray 103 current_directory entry_name 66 | if entry_type = 0 67 | xmath next_index "entry_info_index + 1" 68 | getarray starting_file_offset 2 entry_info_index 69 | math starting_file_offset << 11 70 | getarray finishing_file_offset 2 next_index 71 | math finishing_file_offset << 11 72 | getarray remaining_bytes_within_stored_file 1 entry_info_index 73 | xmath file_size "(finishing_file_offset - starting_file_offset) - remaining_bytes_within_stored_file" 74 | putarray 8 i file_size 75 | math file_offset = starting_file_offset 76 | xmath keywords "current_directory + 1" 77 | set file_name string "" 78 | for name = 0 < keywords 79 | getarray keyword 103 name 80 | string file_name + "/" 81 | string file_name + keyword 82 | next name 83 | putarray 9 i file_name 84 | log file_name file_offset file_size 85 | elif entry_type = 1 86 | if entry_name != ".." 87 | math current_directory + 1 88 | math current_entry = entry_info_index 89 | callfunction parse_gtfs 1 90 | endif 91 | endif 92 | if next_entry == overall_entries 93 | cleanexit 94 | endif 95 | if entry_dead_end = 1 96 | if entry_type != 1 97 | xmath previous_directory "current_directory - 1" 98 | getarray current_entry 102 previous_directory 99 | math current_directory - 1 100 | callfunction parse_gtfs 1 101 | endif 102 | endif 103 | math current_entry + 1 104 | next i 105 | endfunction 106 | elif polyphony_archivextension == "OVL" 107 | get header_limit long 108 | goto 0 109 | do 110 | get file_offset long 111 | get file_size long 112 | savepos curr_off 113 | xmath count "curr_off / 8" 114 | string file_name p "GT2_%02d.OVL.GZ" count 115 | # ^ all i saw from PS1 games are "uppercase" filenames so this script will attempt to stick with protocol if needed 116 | log file_name file_offset file_size 117 | while curr_off < header_limit 118 | else 119 | break 120 | endif 121 | else 122 | break 123 | endif 124 | -------------------------------------------------------------------------------- /gust_ps2.bms: -------------------------------------------------------------------------------- 1 | # Gust - PS2 titles 2 | 3 | get ps2_elf_name filename 4 | 5 | math is_taikenban = 0 6 | if ps2_elf_name == "SLPM_601.12" # Hresvelgr (Trial Version) 7 | # this particular version has its PCM files stored on a separate header 8 | # instead of a singular appended .BIN file for the game exe to latch onto 9 | open FDSE "RPK.BIN" 1 10 | open FDSE "\SD\SD0FP.FP" 2 11 | open FDSE "\SD\SD1FP.FP" 3 12 | open FDSE "\SD\SD2FP.FP" 4 13 | open FDSE "\SD\SD3FP.FP" 5 14 | open FDSE "\PCM\FV.PCM" 6 15 | math is_taikenban = 1 16 | for file_number = 1 <= 6 17 | callfunction handle_hresvelgr_info 1 18 | next file_number 19 | elif ps2_elf_name == "SLPS_200.24" # Hresvelgr 20 | open FDSE "RPK.BIN" 1 21 | open FDSE "SD.BIN" 2 22 | for file_number = 1 <= 2 23 | callfunction handle_hresvelgr_info 1 24 | next file_number 25 | elif ps2_elf_name == "SLPS_200.59" # Hresvelgr: International Edition 26 | open FDSE "RPK.BIN" 1 27 | open FDSE "SDJ.BIN" 2 28 | for file_number = 1 <= 2 29 | callfunction handle_hresvelgr_info 1 30 | next file_number 31 | elif ps2_elf_name == "SLES_505.44" # Jet Ion GP 32 | open FDSE "RPKPAL.BIN" 1 33 | open FDSE "SDOS.BIN" 2 34 | for file_number = 1 <= 2 35 | callfunction handle_hresvelgr_info 1 36 | next file_number 37 | endif 38 | 39 | startfunction handle_hresvelgr_info 40 | /* 41 | up until Hresvelgr: International Edition, \PCM\FV.PCM file table could be approached like this in the game exe 42 | SLPM_601.12 - 0x2e4460 43 | SLPS_200.24 - 0x365d70 44 | the game demo (SLPM_601.12) had said file stored individually. the original game release (SLPS_200.24) had said file stored in SD.BIN with a file table designed specifically for both SD.BIN and \PCM\FV.PCM, with the table for the latter file stored *before* the SD.BIN file table. 45 | later releases (SLPS_200.59) avoid this entirely and has everything stored into SDJ.BIN with a singularly dedicated file table for it in the game exe. 46 | */ 47 | /* 48 | by contrast all .FP files used by the game contain a special file table for each (all within the game exe) 49 | SD0FP.FP - 0x2e40c0(SLPM_601.12) 50 | SD1FP.FP - 0x2e4140(SLPM_601.12) 51 | SD2FP.FP - 0x2e4158(SLPM_601.12) 52 | SD3FP.FP - 0x2e4170(SLPM_601.12) 53 | */ 54 | putarray 0 0 "" 55 | putarray 1 0 "" 56 | putarray 0 1 "" 57 | putarray 2 0 "" 58 | putarray 0 2 "" 59 | putarray 3 0 "" 60 | putarray 0 3 "" 61 | if file_number = 1 62 | if ps2_elf_name == "SLPM_601.12" 63 | goto 0x17cd80 64 | math rpk_files = 7 65 | elif ps2_elf_name == "SLPS_200.24" 66 | goto 0x200980 67 | math rpk_files = 0x10 68 | elif ps2_elf_name == "SLPS_200.59" 69 | goto 0x21fd00 70 | math rpk_files = 0x30 71 | elif ps2_elf_name == "SLES_505.44" 72 | goto 0x22ed00 73 | math rpk_files = 0x2e 74 | endif 75 | for i = 0 < rpk_files 76 | get file_name_string_offset long 77 | callfunction calc_string_value 1 78 | putarray 1 i file_name_string_offset 79 | get file_offset long 80 | math file_offset << 11 81 | putarray 2 i file_offset 82 | get file_size long 83 | putarray 3 i file_size 84 | next i 85 | for i = 0 < rpk_files 86 | getarray file_name_string_offset 1 i 87 | goto file_name_string_offset 88 | get file_name string 89 | getarray file_offset 2 i 90 | getarray file_size 3 i 91 | callfunction extract_file 1 92 | next i 93 | endif 94 | if is_taikenban != 1 95 | if file_number = 2 96 | if ps2_elf_name == "SLPS_200.24" 97 | goto 0x3660b8 98 | elif ps2_elf_name == "SLPS_200.59" 99 | goto 0x37ab10 100 | elif ps2_elf_name == "SLES_505.44" 101 | goto 0x389b58 102 | endif 103 | get pcm_files long 104 | for i = 0 < pcm_files 105 | get file_offset long 106 | math file_offset << 11 107 | putarray i 1 file_offset 108 | get file_size long 109 | putarray i 2 file_Size 110 | next i 111 | if ps2_elf_name == "SLPS_200.24" 112 | goto 0x365950 113 | math i3 = 4 114 | for i2 = 0 < 11 115 | get file_name_string_offset long 116 | get file_02 long 117 | callfunction calc_string_value 1 118 | if i2 == 10 119 | putarray 0 3 file_name_string_offset 120 | else 121 | putarray i3 3 file_name_string_offset 122 | math i3 + 1 123 | endif 124 | next i2 125 | math i3 = 1 126 | for i2 = 0 < 3 127 | get file_01 long 128 | get file_name_string_offset long 129 | get file_03 long 130 | callfunction calc_string_value 1 131 | putarray i3 3 file_name_string_offset 132 | math i3 + 1 133 | next i2 134 | elif ps2_elf_name == "SLPS_200.59" 135 | goto 0x37a724 136 | math i3 = 0 137 | for i2 = 0 < 4 138 | get file_01 long 139 | get file_name_string_offset long 140 | get file_03 long 141 | callfunction calc_string_value 1 142 | putarray i3 3 file_name_string_offset 143 | math i3 + 1 144 | next i2 145 | for i2 = 0 < 55 146 | putarray i3 3 0 147 | math i3 + 1 148 | next i2 149 | elif ps2_elf_name == "SLES_505.44" 150 | goto 0x38976c 151 | math i3 = 0 152 | for i2 = 0 < 4 153 | get file_01 long 154 | get file_name_string_offset long 155 | get file_03 long 156 | callfunction calc_string_value 1 157 | putarray i3 3 file_name_string_offset 158 | math i3 + 1 159 | next i2 160 | for i2 = 0 < 12 161 | putarray i3 3 0 162 | math i3 + 1 163 | next i2 164 | endif 165 | math i2s = 1 166 | for i = 0 < pcm_files 167 | getarray file_offset i 1 168 | getarray file_size i 2 169 | getarray file_name_string_offset i 3 170 | if file_name_string_offset != 0 171 | goto file_name_string_offset 172 | get file_name string 173 | string file_name > ";1" 174 | else 175 | string file_name p "\PCM\%02d.PCM" i2s 176 | math i2s + 1 177 | endif 178 | callfunction extract_file 1 179 | next i 180 | endif 181 | else 182 | if file_number == 2 183 | goto 0x2e40c0 184 | endif 185 | if file_number == 3 186 | goto 0x2e4140 187 | endif 188 | if file_number == 4 189 | goto 0x2e4158 190 | endif 191 | if file_number == 5 192 | goto 0x2e4170 193 | endif 194 | if file_number == 6 195 | goto 0x2e4460 196 | endif 197 | get files long 198 | for i = 0 < files 199 | xmath i2 "i + 1" 200 | set file_name string "" 201 | get file_offset long 202 | math file_offset << 11 203 | get file_size long 204 | if file_number == 2 205 | set file_extension string "" 206 | set pre_name string "" 207 | goto file_offset file_number 208 | get file_sign long file_number 209 | goto -4 file_number SEEK_CUR 210 | if file_sign == 0x53434549 211 | callfunction handle_scei_file 1 212 | elif file_sign == 0x56414270 213 | set file_extension string "VH" 214 | endif 215 | if i < 9 216 | if i = 0 217 | math i3 = 1 218 | endif 219 | set pre_name string "M" 220 | endif 221 | if i > 8 222 | if i = 9 223 | math i3 = 1 224 | endif 225 | set pre_name string "BANK_" 226 | endif 227 | string file_name p "\FP\%s%02d.%s" pre_name i3 file_extension 228 | math i3 + 1 229 | endif 230 | if file_number >= 3 && file_number <= 5 231 | if file_number = 3 && i = 0 232 | math i3 = 1 233 | endif 234 | set pre_name string "\FP\BANK_" 235 | set file_extension string "VB" 236 | if file_number == 5 && i == 1 237 | set file_extension string "BD" 238 | endif 239 | string file_name p "%s%02d.%s" pre_name i3 file_extension 240 | math i3 + 1 241 | endif 242 | if file_number == 6 243 | string file_name p "\FV\%03d.PCM" i2 244 | endif 245 | log file_name file_offset file_size file_number 246 | next i 247 | endif 248 | endfunction 249 | 250 | startfunction calc_string_value 251 | math file_name_string_offset - 0x1ff000 252 | endfunction 253 | 254 | startfunction extract_file 255 | log file_name file_offset file_size file_number 256 | endfunction 257 | 258 | startfunction handle_scei_file 259 | set file_extension string "" 260 | savepos pos_01 file_number 261 | for sc = 0 < 1 262 | goto pos_01 file_number 263 | get is_scei_chunk long file_number 264 | if is_scei_chunk != 0x53434549 265 | break 266 | endif 267 | get scei_chunk_type long file_number 268 | get scei_chunk_size long file_number 269 | if scei_chunk_type = 0x56657273 270 | get scei_bank_info long file_number 271 | xmath is_sound_bank_header "(scei_bank_info >> 24) & 0xff" 272 | if is_sound_bank_header == 0 273 | set file_extension string "SEQ" 274 | elif is_sound_bank_header == 1 275 | set file_extension string "HD" 276 | endif 277 | endif 278 | math pos_01 + scei_chunk_size 279 | next sc 280 | endfunction 281 | -------------------------------------------------------------------------------- /half_life_ps2.bms: -------------------------------------------------------------------------------- 1 | # Half-Life (PS2) - *.PAK 2 | 3 | open FDDE "pak" 4 | 5 | comtype zlib 6 | get pak_identifier long 7 | if pak_identifier = 0x4b434150 # "PACK" 8 | get pak_file_info_offset long 9 | get pak_file_info_header_size long 10 | goto pak_file_info_offset 11 | xmath pak_files "pak_file_info_header_size >> 6" 12 | for i = 0 < pak_files 13 | getdstring file_name 0x38 14 | get file_offset long 15 | get file_size long 16 | log file_name file_offset file_size 17 | next i 18 | else 19 | get zlib_sign short 20 | if zlib_sign == 0xda78 21 | math original_size = pak_identifier 22 | get pak_basename filename 23 | get pak_basesize asize 24 | math pak_basesize - 4 25 | string pak_finalname p "[DECOMPRESSED]%s" pak_basename 26 | clog pak_finalname 4 pak_basesize original_size 27 | print " this script can now be re-used on the decompressed PAK file. " 28 | else 29 | print " what am i looking for exactly? " 30 | endif 31 | endif 32 | -------------------------------------------------------------------------------- /headhunter_ahff.bms: -------------------------------------------------------------------------------- 1 | # Headhunter (Dreamcast, PS2) - *.AHF 2 | 3 | idstring "AHFF" 4 | get ahf_02 long 5 | get ahf_files long 6 | get ahf_offset long 7 | math ahf_offset + 0x10 8 | goto ahf_offset 9 | for i = 0 < ahf_files 10 | get file_info_offset long 11 | savepos ahff_temp_position 12 | math file_info_offset + 0x10 13 | goto file_info_offset 14 | get file_offset long 15 | get file_size long 16 | get ahff_03 long 17 | get file_name string 18 | log file_name file_offset file_size 19 | padding 4 20 | goto ahff_temp_position 21 | next i 22 | -------------------------------------------------------------------------------- /headhunter_pic.bms: -------------------------------------------------------------------------------- 1 | # Headhunter (PS2) - *.pic->*.tga 2 | 3 | open FDDE "pic" 0 4 | get pic_path fullname 5 | get pic_name basename 6 | get pic_size asize 7 | math pic_offset = 8 8 | 9 | get pic_color_map_entries short 10 | get pic_height short 11 | get pic_width short 12 | get pic_04 short 13 | xmath raw_image_offset "(pic_color_map_entries << 2)" 14 | xmath raw_image_size "(pic_size - pic_offset) - raw_image_offset" 15 | math pic_offset + raw_image_offset 16 | if pic_color_map_entries == 0 17 | xmath pixel_entries "raw_image_size >> 2" 18 | else 19 | math pixel_entries = raw_image_size 20 | endif 21 | for i = 0 < pic_color_map_entries 22 | get color_map_info long 23 | xmath attribute "(color_map_info >> 24) & 0xff" 24 | putarray 4 i attribute 25 | xmath blue "(color_map_info >> 16) & 0xff" 26 | putarray 3 i blue 27 | xmath green "(color_map_info >> 8) & 0xff" 28 | putarray 2 i green 29 | xmath red "color_map_info & 0xff" 30 | putarray 1 i red 31 | next i 32 | 33 | log MEMORY_FILE 0 0 34 | put 0 byte MEMORY_FILE 35 | put 0 byte MEMORY_FILE 36 | put 2 byte MEMORY_FILE 37 | put 0 short MEMORY_FILE 38 | put 0 short MEMORY_FILE 39 | put 0x20 byte MEMORY_FILE 40 | put 0 short MEMORY_FILE 41 | put 0 short MEMORY_FILE 42 | put pic_height short MEMORY_FILE 43 | put pic_width short MEMORY_FILE 44 | put 0x20 byte MEMORY_FILE 45 | xmath image_descriptor "(0 << 6) | (1 << 5) | (0 << 4) | 8" 46 | put image_descriptor byte MEMORY_FILE 47 | goto pic_offset 48 | for px = 0 < pixel_entries 49 | if pic_color_map_entries == 0 50 | get red byte 51 | get green byte 52 | get blue byte 53 | get attribute byte 54 | put blue byte MEMORY_FILE 55 | put green byte MEMORY_FILE 56 | put red byte MEMORY_FILE 57 | put attribute byte MEMORY_FILE 58 | elif pic_color_map_entries == 0x10 59 | get image_byte byte 60 | for nibble = 0 < 2 61 | if nibble = 0 62 | xmath image_nibble "(image_byte >> 4) & 0x0f" 63 | elif nibble = 1 64 | xmath image_nibble "image_byte & 0x0f" 65 | endif 66 | getarray red 1 image_nibble 67 | getarray green 2 image_nibble 68 | getarray blue 3 image_nibble 69 | getarray attribute 4 image_nibble 70 | put blue byte MEMORY_FILE 71 | put green byte MEMORY_FILE 72 | put red byte MEMORY_FILE 73 | put attribute byte MEMORY_FILE 74 | next nibble 75 | elif pic_color_map_entries == 0x100 76 | get image_byte byte 77 | getarray red 1 image_byte 78 | getarray green 2 image_byte 79 | getarray blue 3 image_byte 80 | getarray attribute 4 image_byte 81 | put blue byte MEMORY_FILE 82 | put green byte MEMORY_FILE 83 | put red byte MEMORY_FILE 84 | put attribute byte MEMORY_FILE 85 | endif 86 | next px 87 | 88 | string tga_name p "%s.TGA" pic_name 89 | get tga_size asize MEMORY_FILE 90 | log tga_name 0 tga_size MEMORY_FILE 91 | -------------------------------------------------------------------------------- /hh2_ps2.bms: -------------------------------------------------------------------------------- 1 | # Headhunter: Redemption (PS2) 2 | 3 | putarray 0 0 "FS.DAT" 4 | putarray 0 1 "FSKOLME.DAT" 5 | putarray 0 2 "FSPIENI.DAT" 6 | putarray 0 3 "FSPUKKI.DAT" 7 | 8 | for i = 0 < 4 9 | getarray archive_name 0 i 10 | open FDSE archive_name 0 EXISTS 11 | if EXISTS == 1 12 | callfunction parse_archive_info 1 13 | endif 14 | next i 15 | 16 | startfunction parse_archive_info 17 | math archive_base_offset = 1024 18 | goto -0x800 19 | get archive_header_offset long 20 | math archive_header_offset + archive_base_offset 21 | math archive_header_offset << 11 22 | get archive_header_size long 23 | get archive_header_entries long 24 | 25 | goto archive_header_offset 26 | for j = 0 < archive_header_entries 27 | get name_hash long 28 | get file_offset long 29 | math file_offset + archive_base_offset 30 | math file_offset << 11 31 | get file_size long 32 | 33 | string file_name p "%08x." name_hash 34 | log file_name file_offset file_size 35 | next j 36 | endfunction 37 | -------------------------------------------------------------------------------- /hh_ps2.bms: -------------------------------------------------------------------------------- 1 | # Headhunter (PS2) 2 | 3 | putarray 0 0 "hhps2.afs" 4 | putarray 0 1 "hhps2s.afs" 5 | putarray 0 2 "hhps2m0.afs" 6 | putarray 0 3 "hhps2m1.afs" 7 | 8 | open FDSE "hhps2.afs" 9 | 10 | get afs_files long 11 | get hh02 long 12 | goto 0x800 13 | for i = 0 < afs_files 14 | get file_offset long 15 | get file_size long 16 | get name_hash long 17 | get file_04 long 18 | get archive_number byte 19 | getarray archive_name 0 archive_number 20 | getdstring file_name 0xef 21 | strlen name_size file_name 22 | 23 | open FDSE archive_name 1 24 | log file_name file_offset file_size 1 25 | next i 26 | -------------------------------------------------------------------------------- /hype_the_time_quest_ps2_sound.bms: -------------------------------------------------------------------------------- 1 | # Hype: The Time Quest (PS2) - [BNM/VB/VSB].BF 2 | 3 | get extension_name basename 4 | string sound_archive_name p "%s.BF" extension_name 5 | 6 | if extension_name == "BNM" || extension_name == "VB" || extension_name == "VSB" 7 | open FDSE sound_archive_name 0 8 | get bank_files short 9 | for i = 0 < bank_files 10 | get bank_number short 11 | get current_file_offset long 12 | get next_file_offset long 13 | xmath file_size "next_file_offset - current_file_offset" 14 | string file_name p "BNK_%d.%s" bank_number extension_name 15 | log file_name current_file_offset file_size 16 | next i 17 | endif 18 | -------------------------------------------------------------------------------- /ico_df.bms: -------------------------------------------------------------------------------- 1 | # ICO - *.DF files 2 | 3 | get DF_NAME1 filename 4 | get DF_EXT1 extension 5 | 6 | if DF_NAME1 == "DATA.DF" 7 | # shamelessly copy-pasted from aluigi's teamico.bms script, which i requested some time ago in some zenhax thread 8 | comtype deflate_noerror 9 | get FILES long 10 | for i = 0 < FILES 11 | getdstring NAME 0x20 12 | get OFFSET long 13 | get SIZE long 14 | set EXT extension NAME 15 | if EXT == "df" 16 | clog NAME OFFSET SIZE SIZE 17 | else 18 | log NAME OFFSET SIZE 19 | endif 20 | next i 21 | else 22 | if DF_EXT1 == "DF" 23 | get DF_FILES long 24 | get DF_RANDOM long 25 | getbits DF_DUMMY1 64 26 | for i = 0 < DF_FILES 27 | get DF01 long 28 | get DF02 long 29 | get DF03 long 30 | get DF_FSIZE long 31 | getdstring DF_FNAME 0x200 32 | get DF05 long 33 | get DF_FOFFSET long 34 | get DF07 long 35 | get DF08 long 36 | get DF09 long 37 | log DF_FNAME DF_FOFFSET DF_FSIZE 38 | next i 39 | endif 40 | endif 41 | -------------------------------------------------------------------------------- /in2_tag_bin.bms: -------------------------------------------------------------------------------- 1 | # Quiz and Variety Suku Suku Inufuku 2 (IN2 Ver. A) - DATA[.TAG/.BIN] 2 | 3 | open FDDE "tag" 0 4 | open FDDE "bin" 1 5 | 6 | get TAG_SIZE asize 7 | idstring "****TAG_DATA****" 8 | do 9 | get TAG_INFO_ENTRIES long 10 | get TAG_INFO_OFF long 11 | savepos TAG_OFF1 12 | if TAG_INFO_OFF != 0 13 | goto TAG_INFO_OFF 14 | for i = 0 < TAG_INFO_ENTRIES 15 | getdstring TAG_FNAME 0x10 16 | get TAG_02 long 17 | get TAG_FOFFSET long 18 | get TAG_FSIZE1 long 19 | get TAG_FSIZE2 long 20 | log TAG_FNAME TAG_FOFFSET TAG_FSIZE1 1 21 | next i 22 | endif 23 | goto TAG_OFF1 24 | while TAG_OFF1 < 0x410 # (max number + 0x10) 25 | -------------------------------------------------------------------------------- /irxarc_bin.bms: -------------------------------------------------------------------------------- 1 | # BANDAI NAMCO Studios (as NAMCO TALES STUDIO, PS2 era) - irxarc.bin 2 | # --- 3 | # Tales of Symphonia (PS2) - from "Symphonia Team" 4 | # Tales of the Abyss (PS2) - from "Symphonia Team" 5 | 6 | open FDSE "irxarc.bin" 7 | get irxarc_files long 8 | math file_info_offset = 0x40 9 | math file_name_offset = 0x50 10 | math file_offset = 0x180 11 | for i = 0 < irxarc_files 12 | goto file_info_offset 13 | get file_size long 14 | goto file_name_offset 15 | getdstring file_name 0x30 16 | get irx_parameters string 17 | log file_name file_offset file_size 18 | math file_offset + file_size 19 | math file_info_offset = file_offset 20 | math file_name_offset = file_offset 21 | math file_name_offset + 0x10 22 | math file_offset + 0x140 23 | next i 24 | -------------------------------------------------------------------------------- /james_camerons_avatar_the_game_pak.bms: -------------------------------------------------------------------------------- 1 | # Ubisoft - *.pak(PAK!) 2 | # --- 3 | # James Cameron's Avatar: The Game (Windows Vista, PlayStation 3?, Xbox 360) 4 | 5 | math max_chunk_size = 0x10000 6 | 7 | goto 0 8 | idstring "PAK!" 9 | get pak_01 long 10 | if pak_01 != 4 11 | print " unknown PAK version number " 12 | cleanexit 13 | endif 14 | get pak_info_offset1 long 15 | goto pak_info_offset1 16 | get compressed_info_size long 17 | xmath pak_info_offset2 "pak_info_offset1 + compressed_info_size" 18 | goto pak_info_offset2 19 | get pak_info_chunks long 20 | for i = 0 < pak_info_chunks 21 | get chunk1 long 22 | putarray 0 i chunk1 23 | get chunk2 long 24 | xmath chunk2_1 "chunk2 & 0x7fffffff" 25 | putarray 1 i chunk2_1 26 | xmath chunk2_2 "(chunk2 & 0x80000000) >> 31" 27 | putarray 2 i chunk2_2 28 | xmath chunk2_3 "chunk2_1 + pak_info_offset1" 29 | putarray 3 i chunk2_3 30 | next i 31 | xmath pak_info_c2 "pak_info_chunks - 1" 32 | for i1 = 0 < pak_info_chunks 33 | getarray chunk1 0 i1 34 | getarray chunk2_1 1 i1 35 | if i1 != pak_info_c2 36 | xmath i2 "i1 + 1" 37 | getarray chunk1_1 0 i2 38 | getarray chunk2_1_1 1 i2 39 | xmath chunk3 "chunk1_1 - chunk1" 40 | xmath chunk4 "chunk2_1_1 - chunk2_1" 41 | putarray 4 i1 chunk3 42 | putarray 5 i1 chunk4 43 | else 44 | putarray 4 i1 0 45 | putarray 5 i1 0 46 | endif 47 | next i1 48 | xmath pak_info_alloc "pak_info_chunks * max_chunk_size" 49 | putvarchr MEMORY_FILE pak_info_alloc 0 50 | log MEMORY_FILE 0 0 51 | append 52 | for i3 = 0 < pak_info_chunks 53 | getarray chunk1 0 i3 54 | getarray chunk2_1 1 i3 55 | getarray chunk2_2 2 i3 56 | getarray chunk2_3 3 i3 57 | getarray chunk3 4 i3 58 | getarray chunk4 5 i3 59 | if chunk2_2 != 1 60 | log MEMORY_FILE chunk2_3 chunk3 61 | else 62 | clog MEMORY_FILE chunk2_3 chunk4 chunk3 63 | endif 64 | next i3 65 | append 66 | 67 | goto 0 MEMORY_FILE 68 | comtype lzo1x 69 | get info1 byte MEMORY_FILE 70 | if info1 != 1 71 | print " unknown PAK info number. " 72 | cleanexit 73 | endif 74 | get pak_files long MEMORY_FILE 75 | math pak_file_info_offset1 = 5 76 | for steps = 0 < 2 77 | for i4 = 0 < pak_files 78 | get file_offset long MEMORY_FILE 79 | get file_size long MEMORY_FILE # full filesize 80 | get file_name_hash long MEMORY_FILE 81 | xmath file_chunks1 "file_size / max_chunk_size" 82 | xmath file_chunks2 "file_size % max_chunk_size" 83 | if file_chunks2 != 0 84 | math file_chunks1 + 1 85 | endif 86 | if steps == 0 87 | for j1 = 0 < file_chunks1 88 | get file_chunk1 short MEMORY_FILE 89 | get file_chunk2 short MEMORY_FILE 90 | next j1 91 | elif steps == 1 92 | savepos temp1 MEMORY_FILE 93 | goto pak_file_info_offset2 MEMORY_FILE 94 | get file_creation_date time64 MEMORY_FILE 95 | get file_name_string_size byte MEMORY_FILE 96 | getdstring file_name file_name_string_size MEMORY_FILE 97 | savepos pak_file_info_offset2 MEMORY_FILE 98 | goto temp1 MEMORY_FILE 99 | callfunction extract_file 1 100 | endif 101 | next i4 102 | if steps == 0 103 | savepos pak_file_info_offset2 MEMORY_FILE 104 | endif 105 | goto pak_file_info_offset1 MEMORY_FILE 106 | next steps 107 | 108 | startfunction extract_file 109 | putvarchr MEMORY_FILE2 file_size 0 110 | log MEMORY_FILE2 0 0 111 | math chunk_offset = file_offset 112 | math remaining_size = file_size 113 | xmath file_chunks3 "file_chunks1 - 1" 114 | append 115 | for j2 = 0 < file_chunks1 116 | math chunk_is_compressed = 1 117 | get file_chunk11 short MEMORY_FILE 118 | get file_chunk21 short MEMORY_FILE 119 | math compressed_size = 0 120 | math decompressed_size = 0 121 | if file_chunk21 == 0 122 | math compressed_size = file_chunk11 123 | if file_chunks2 == 1 124 | math decompressed_size = file_size 125 | else 126 | if j2 == file_chunks3 127 | math decompressed_size = remaining_size 128 | else 129 | math decompressed_size = max_chunk_size 130 | endif 131 | endif 132 | math remaining_size - decompressed_size 133 | elif file_chunk21 == 0xffff 134 | math chunk_is_compressed = 0 135 | if file_chunk11 == 0 136 | math remaining_size - max_chunk_size 137 | math compressed_size = max_chunk_size 138 | math decompressed_size = compressed_size 139 | else 140 | xmath compressed_size "(file_chunk11 ^ file_chunk21) + 1" 141 | math decompressed_size = compressed_size 142 | math remaining_size - decompressed_size 143 | endif 144 | endif 145 | if chunk_is_compressed != 0 146 | clog MEMORY_FILE2 chunk_offset compressed_size decompressed_size 0 147 | else 148 | log MEMORY_FILE2 chunk_offset compressed_size 0 149 | endif 150 | math chunk_offset + compressed_size 151 | next j2 152 | append 153 | log file_name 0 file_size MEMORY_FILE2 154 | log MEMORY_FILE2 0 0 155 | endfunction 156 | -------------------------------------------------------------------------------- /kidou_senshi_gundam_ichinen_sensou.bms: -------------------------------------------------------------------------------- 1 | # Kidou Senshi Gundam - Inchinen Sensou (PS2) 2 | 3 | get archive_name basename 4 | get archive_ext extension 5 | 6 | if archive_name & "DAT0" 7 | if archive_ext == "DAT" 8 | print "ALL.BD duplicate" 9 | cleanexit 10 | endif 11 | elif archive_name == "ALL" 12 | open FDDE "hd" 0 13 | open FDDE "bd" 1 14 | 15 | get files long 0 16 | for i = 0 < files 17 | get name_off long 18 | get offset long 19 | get size long 20 | 21 | savepos tmp1 22 | goto name_off 23 | get name string 24 | goto tmp1 25 | 26 | log name offset size 1 27 | next i 28 | elif archive_name == "UNITARY" 29 | get unitary_sign long 30 | get dummy2 long 31 | get header_size long 32 | get files long 33 | xmath base_off "header_size && 0x800" 34 | for i = 0 < files 35 | get dummy5 long # primary offset 36 | get dummy6 long # secondary offset 37 | get size long # self-explanatory 38 | get dummy8 long # always zero 39 | 40 | xmath offset "(dummy5 << 11) + base_off" 41 | string fname p "%s_%04d." archive_name i 42 | log fname offset size 43 | next i 44 | endif 45 | -------------------------------------------------------------------------------- /killzone_beta.bms: -------------------------------------------------------------------------------- 1 | # Killzone Beta (PS2) 2 | 3 | open FDSE "FILES.DAT" 0 4 | 5 | get dat_basename basename 6 | get dat_header_size long 7 | get dat_files long 8 | get dat_03 short 9 | get dat_04 short 10 | get dat_05 long 11 | get dat_06 long 12 | get dat_07 long 13 | for i = 0 < dat_files 14 | get file_size long 15 | get file_offset long 16 | get file_name_offset long 17 | math file_name_offset + 0x18 18 | savepos dat_tmp1 19 | goto file_name_offset 20 | get file_name string 21 | goto dat_tmp1 22 | get dat_number long 23 | if dat_number == 0 24 | string archive_name p "%s.DAT" dat_basename 25 | else 26 | string archive_name p "%s%02d.DAT" dat_basename dat_number 27 | endif 28 | open FDSE archive_name 1 29 | log file_name file_offset file_size 1 30 | next i 31 | -------------------------------------------------------------------------------- /kinetica_wad.bms: -------------------------------------------------------------------------------- 1 | # Kinetica (PS2) - *.WAD 2 | 3 | open FDDE "wad" 0 4 | 5 | get wad_size asize 0 6 | savepos offset 7 | do 8 | goto offset 9 | get dummy1 long 10 | get type long 11 | get size long 12 | get dummy4 long 13 | getdstring name 0x10 14 | savepos offset 15 | if type == 0x18 16 | math size == 0 17 | endif 18 | string fname p "%04x/%s" type name 19 | if size != 0 20 | log fname offset size 21 | endif 22 | math offset += size 23 | math offset x= 0x10 24 | while offset < wad_size 25 | -------------------------------------------------------------------------------- /kojima_productions/README.md: -------------------------------------------------------------------------------- 1 | hello 2 | -------------------------------------------------------------------------------- /kojima_productions/kojima_productions_ps2_ipk.bms: -------------------------------------------------------------------------------- 1 | # ipk archive (MGS2, AZOE/ZOE2, MGS3) 2 | 3 | open FDDE "ipk" 4 | 5 | get ipk_size asize 6 | math ipk_offset = 0 7 | do 8 | goto ipk_offset 9 | math limit = 4 10 | math mode = 1 11 | callfunction ipk_dec_01 1 12 | getarray aligned_file_size 1 0 13 | getarray file_size 1 1 14 | getarray file_name_string_size 1 2 15 | getarray file_04 1 3 16 | if aligned_file_size != 0 17 | xmath limit "aligned_file_size >> 2" 18 | math mode = 0 19 | callfunction ipk_dec_01 1 20 | math file_name_string_location = file_size 21 | goto file_name_string_location MEMORY_FILE 22 | getdstring file_name file_name_string_size MEMORY_FILE 23 | log file_name 0 file_size MEMORY_FILE 24 | endif 25 | math ipk_offset + aligned_file_size 26 | math ipk_offset + 0x10 27 | while ipk_offset < ipk_size 28 | 29 | startfunction ipk_dec_01 30 | if mode = 0 31 | putvarchr MEMORY_FILE aligned_file_size 0 32 | log MEMORY_FILE 0 0 33 | endif 34 | if mode = 1 35 | math ipk_number_01 == 0x7E8A6B4C 36 | math ipk_number_02 == 0xA84E6B2E 37 | endif 38 | for x = 0 < limit 39 | get ipk_byte long 40 | math ipk_byte ^ ipk_number_01 41 | if mode = 0 42 | put ipk_byte long MEMORY_FILE 43 | elif mode = 1 44 | putarray 1 x ipk_byte 45 | endif 46 | math ipk_number_01 + ipk_number_02 47 | next x 48 | endfunction 49 | -------------------------------------------------------------------------------- /kojima_productions/metal_gear_solid_2_substance_xbox.bms: -------------------------------------------------------------------------------- 1 | # Metal Gear Solid 2: Substance (Xbox) 2 | 3 | get archive_name basename 4 | get archive_size asize 5 | string disc_name = archive_name 6 | string disc_name > "_" 7 | string disc_name < "disc" 8 | string disc_number = archive_name 9 | string disc_number - disc_name 10 | string disc_number > "_" 11 | string disc_partition = archive_name 12 | string disc_partition ! disc_name 13 | string disc_partition ! disc_number 14 | string disc_partition ! "_" 15 | 16 | if disc_name == "disc" 17 | if disc_number == "1" | disc_number == "2" 18 | if disc_partition != "0" 19 | print "oh come on..." 20 | cleanexit 21 | else 22 | math archive_offset_per_partition = 0 23 | math partition_number = 0 24 | for partition_check = 0 <= partition_number 25 | string archive_name_02 p "disc%s_%d.dat" disc_number disc_partition 26 | putarray 1 partition_check archive_name_02 27 | open FDSE archive_name_02 1 EXISTS 28 | if EXISTS == 1 29 | get archive_size_02 asize 1 30 | math archive_size_02 >> 11 31 | putarray 2 partition_check archive_offset_per_partition 32 | math archive_offset_per_partition + archive_size_02 33 | math archive_size_limit_per_partition == archive_offset_per_partition 34 | putarray 3 partition_check archive_size_limit_per_partition 35 | putarray 4 partition_check archive_size_02 36 | math disc_partition + 1 37 | else 38 | break 39 | endif 40 | math partition_number + 1 41 | next partition_check 42 | get files long 43 | for i = 0 < files 44 | getdstring file_name 0x10 45 | get file_offset long 46 | get file_size long 47 | math archive_chunks_per_file = 0 48 | math last_archive_chunk_per_file = 0 49 | math pass = 0 50 | math file_size_exp_02 = 0 51 | math file_size_exp_03 = file_size 52 | append 53 | for j = 0 <= partition_number 54 | getarray archive_name_per_partition 1 j 55 | getarray archive_offset_per_partition 2 j 56 | getarray archive_size_limit_per_partition 3 j 57 | getarray archive_size_per_partition 4 j 58 | if file_offset >= archive_offset_per_partition && file_offset <= archive_size_limit_per_partition 59 | xmath file_offset_per_archive_chunk "file_offset - archive_offset_per_partition" 60 | math pass = 1 61 | endif 62 | if pass = 1 63 | if archive_chunks_per_file = 0 64 | math file_size_exp_01 = archive_size_per_partition 65 | math file_size_exp_01 - file_offset_per_archive_chunk 66 | else 67 | math file_offset_per_archive_chunk = 0 68 | math file_size_exp_01 = archive_size_per_partition 69 | endif 70 | math file_size_exp_02 + file_size_exp_01 71 | if file_size_exp_02 >= file_size 72 | math last_archive_chunk_per_file = 1 73 | endif 74 | if last_archive_chunk_per_file = 0 75 | math file_size_per_archive_chunk = file_size_exp_01 76 | elif last_archive_chunk_per_file = 1 77 | if archive_chunks_per_file = 0 78 | math file_size_per_archive_chunk = file_size 79 | else 80 | math file_size_per_archive_chunk = file_size_exp_03 81 | endif 82 | endif 83 | xmath file_offset_per_archive_chunk_02 "file_offset_per_archive_chunk << 11" 84 | xmath file_size_per_archive_chunk_02 "file_size_per_archive_chunk << 11" 85 | open FDSE archive_name_per_partition 1 86 | log file_name file_offset_per_archive_chunk_02 file_size_per_archive_chunk_02 1 87 | 88 | if last_archive_chunk_per_file = 1 89 | break 90 | else 91 | math archive_chunks_per_file + 1 92 | endif 93 | math file_size_exp_03 - file_size_exp_01 94 | endif 95 | next j 96 | append 97 | next i 98 | endif 99 | endif 100 | endif 101 | -------------------------------------------------------------------------------- /lair.bms: -------------------------------------------------------------------------------- 1 | # Lair (PS3) - *.dat/*.data/*.txt 2 | 3 | endian big 4 | comtype unzip_dynamic 5 | 6 | math parse_data = 1 7 | 8 | get ext extension 9 | if ext == "dat" 10 | get base_off long 11 | get files long 12 | get dat03 long 13 | get dat04 long 14 | for i = 0 < files 15 | get name_off long 16 | get dat06 long 17 | get dat07 long 18 | get offset long 19 | get uncompressed_size long 20 | get compressed_size long 21 | 22 | savepos tmp1 23 | goto name_off 24 | get name string 25 | goto offset 26 | if compressed_size == 0 27 | if parse_data = 0 28 | log name offset uncompressed_size 29 | elif parse_data = 1 30 | log temporary_file offset uncompressed_size 31 | endif 32 | else 33 | idstring "RCMP" 34 | get rcmp01 long 35 | get rcmp_uncompressed_size long 36 | get rcmp_compressed_size long 37 | get rcmp_hash long 38 | get rcmp05 long 39 | savepos rcmp_offset 40 | if parse_data = 0 41 | clog name rcmp_offset rcmp_compressed_size rcmp_uncompressed_size 42 | elif parse_data = 1 43 | clog temporary_file rcmp_offset rcmp_compressed_size rcmp_uncompressed_size 44 | endif 45 | endif 46 | goto tmp1 47 | 48 | if parse_data = 1 49 | open "." temporary_file 1 50 | math filenum = 1 51 | 52 | get subfile_base_number long filenum 53 | for 54 | get subfile_name_off long filenum 55 | if subfile_name_off == 0 56 | break 57 | endif 58 | get subfile_offset long filenum 59 | math subfile_offset + subfile_base_number 60 | get subfile_size long filenum 61 | savepos tmp2 filenum 62 | goto subfile_name_off filenum 63 | get subfile_name string filenum 64 | goto tmp2 filenum 65 | 66 | set backup_name string name 67 | string subfile_filename p "[%s].%s" backup_name subfile_name 68 | log subfile_filename subfile_offset subfile_size filenum 69 | next 70 | endif 71 | next i 72 | elif ext == "data" 73 | idstring "FCLC" 74 | get fclc01 long 75 | get fclc_shaders long 76 | get fclc_start_off long 77 | for i = 0 < fclc_shaders 78 | get fclc04 long 79 | get fclc05 long 80 | get fclc06 long 81 | next i 82 | elif ext == "txt" 83 | get txt_filesize asize 84 | get base_filename basename 85 | if base_filename & ".dat" 86 | open FDSE base_filename 1 87 | math a = 0 88 | math b = 0 89 | for 90 | get base_line line 91 | savepos txt_off 92 | if base_line == "[RC:0005]" 93 | get base_loading_info line 94 | elif base_line == "[resources]" 95 | for 96 | get base_resource_info line 97 | savepos txt_off 98 | if base_resource_info == "[/resources]" 99 | break 100 | else 101 | string file_elements_1 S base_resource_info name hash 102 | putarray 1 a name 103 | putarray 2 a hash 104 | math a + 1 105 | endif 106 | next 107 | elif base_line == "[targets]" 108 | for 109 | get base_target_info line 110 | savepos txt_off 111 | if base_target_info == "[/targets]" 112 | break 113 | else 114 | string file_elements_2 S base_target_info hash1 hash2 uncompressed_size compressed_size file_position unknown 115 | putarray 3 b hash1 116 | putarray 4 b hash2 117 | putarray 5 b uncompressed_size 118 | putarray 6 b compressed_size 119 | putarray 7 b file_position 120 | putarray 8 b unknown 121 | math b + 1 122 | endif 123 | next 124 | elif base_line == "[/RC:0005]" 125 | break 126 | endif 127 | next 128 | endif 129 | endif 130 | -------------------------------------------------------------------------------- /mgs2_stream.bms: -------------------------------------------------------------------------------- 1 | # Kojima Productions - chunked multimedia formats(cutscene, movie, sound/bgm/voice, etc.) 2 | 3 | get STREAM_BNAME basename 4 | get STREAM_ECHECK long 5 | endian guess STREAM_ECHECK 6 | goto 0 7 | 8 | #math VIDEO_HANDLE = 0 9 | math VIDEO_CHUNKS = 0 10 | math MTAF_HANDLE = 0 11 | math MTAF_CHUNKS = 0 12 | 13 | log MEMORY_FILE 0 0 14 | append 15 | do 16 | savepos OFFSET1 17 | get DUMMY01 long 18 | get SIZE1 long 19 | get COUNT1 long 20 | get ALTSIZE1 long 21 | savepos OFFSET2 22 | xmath SIZE2 "SIZE1 - 0x10" 23 | 24 | # these extensions are unconfirmed for now 25 | /* 26 | if DUMMY01 == 0x00000001 27 | string DUMMY01_EXT p "_01.pcm" 28 | elif DUMMY01 == 0x00000002 29 | string DUMMY01_EXT p "_01.dmx" 30 | elif DUMMY01 == 0x00000003 31 | string DUMMY01_EXT p "_02.dmx" 32 | elif DUMMY01 == 0x00000004 33 | string DUMMY01_EXT p "_01.scn" 34 | elif DUMMY01 == 0x00000005 35 | string DUMMY01_EXT p "_03.dmx" 36 | elif DUMMY01 == 0x0000000e 37 | string DUMMY01_EXT p ".pss" 38 | elif DUMMY01 == 0x0000000f 39 | string DUMMY01_EXT p ".ipu" 40 | elif DUMMY01 == 0x00000020 41 | if VIDEO_CHUNKS = 0 42 | savepos SDSTREAM_TMP1 43 | goto OFFSET2 44 | get VIDEO_SIGN1 long 45 | get VIDEO_SIGN2 long 46 | get VIDEO_SIGN3 long 47 | get VIDEO_SIGN4 long 48 | if VIDEO_SIGN1 == 0x75b22630 && VIDEO_SIGN2 == 0x11cf668e && VIDEO_SIGN3 == 0xaa00d9a6 && VIDEO_SIGN4 == 0x6cce6200 49 | string DUMMY01_EXT p ".wmv" 50 | endif 51 | if VIDEO_SIGN1 == 0x20000000# && VIDEO_SIGN2 == 0x70797466 && VIDEO_SIGN3 == 0x6d6f7369 && VIDEO_SIGN4 == 0x00020000 52 | string DUMMY01_EXT p ".mp4" 53 | endif 54 | goto SDSTREAM_TMP1 55 | endif 56 | math VIDEO_CHUNKS + 1 57 | elif DUMMY01 == 0x00010001 58 | string DUMMY01_EXT p "_02.pcm" 59 | elif DUMMY01 == 0x00020001 60 | string DUMMY01_EXT p "_03.pcm" 61 | elif DUMMY01 == 0x00030001 62 | string DUMMY01_EXT p ".msf" 63 | elif DUMMY01 == 0x00040001 64 | if SIZE2 == ALTSIZE1 65 | # do nothing 66 | else 67 | math SIZE2 == ALTSIZE1 68 | endif 69 | string DUMMY01_EXT p ".xwma" 70 | elif DUMMY01 == 0x00050001 71 | string DUMMY01_EXT p ".9tav" 72 | elif DUMMY01 == 0x00110001 73 | string DUMMY01_EXT p ".mtaf" 74 | math MTAF_HANDLE = 1 75 | else 76 | string DUMMY01_EXT p ".%08x" DUMMY01 77 | endif 78 | */ 79 | if DUMMY01 == 0x00010001 80 | math MTAF_HANDLE = 1 81 | elif DUMMY01 == 0x00040001 82 | if SIZE2 == ALTSIZE1 83 | # do nothing 84 | else 85 | math SIZE2 == ALTSIZE1 86 | endif 87 | elif DUMMY01 == 0x00110001 88 | math MTAF_HANDLE = 1 89 | endif 90 | 91 | string DUMMY01_EXT p ".%08x" DUMMY01 92 | string STREAM_FNAME1 p "%s%s" STREAM_BNAME DUMMY01_EXT 93 | 94 | if MTAF_HANDLE = 0 95 | if DUMMY01 != 0x10 && DUMMY01 != 0xf0 96 | log STREAM_FNAME1 OFFSET2 SIZE2 97 | endif 98 | elif MTAF_HANDLE = 1 99 | if MTAF_CHUNKS != 0 100 | if ALTSIZE1 != 0 101 | if DUMMY01 != 0x10 && DUMMY01 != 0xf0 102 | log STREAM_FNAME1 OFFSET2 SIZE2 103 | endif 104 | endif 105 | else 106 | log STREAM_FNAME1 OFFSET2 SIZE2 107 | endif 108 | math MTAF_CHUNKS + 1 109 | math MTAF_HANDLE = 0 110 | endif 111 | 112 | math OFFSET1 += SIZE1 113 | goto OFFSET1 114 | while DUMMY01 != 0xf0 115 | append 116 | -------------------------------------------------------------------------------- /mhw_chunk.bms: -------------------------------------------------------------------------------- 1 | # Monster Hunter: World (PS4/XboxOne/Steam) - chunk#.bin 2 | 3 | comtype oodle 4 | 5 | get chunk_name basename 6 | get chunk_sign long 7 | if chunk_sign != 0x00504d43 8 | break 9 | endif 10 | get chunks long 11 | append 12 | for i = 0 < chunks 13 | get chunk_info longlong 14 | xmath chunk_offset "(chunk_info & 0xffffffffff000000) >> 24" 15 | xmath chunk_size "(chunk_info & 0x000000000fffff0) >> 4" 16 | xmath chunk_type "chunk_info & 0x00000000000000f" 17 | if chunk_type == 0 18 | log chunk_name chunk_offset 0x40000 19 | elif chunk_type == 2 20 | clog chunk_name chunk_offset chunk_size 0x40000 21 | endif 22 | next i 23 | append 24 | -------------------------------------------------------------------------------- /mhw_pkg.bms: -------------------------------------------------------------------------------- 1 | # Monster Hunter: World (PS4/XboxOne/Steam) - post-processed chunk#.bin 2 | 3 | get pkg_sign long 4 | if pkg_sign != 0x20474b50 5 | break 6 | endif 7 | get entry_name_string_size long 8 | get sub_entry_name_string_size long 9 | get entries long 10 | get total_entries long 11 | goto 0x100 12 | for i = 0 < entries 13 | getdstring entry_name entry_name_string_size 14 | get sub_entries long 15 | for j = 0 < sub_entries 16 | getdstring sub_entry_name sub_entry_name_string_size 17 | getdstring remnants_of_a_previous_sub_entry_name sub_entry_name_string_size 18 | get sub_entry_size longlong 19 | get sub_entry_offset longlong 20 | get sub_entry_type long 21 | get sub_entry_04 long 22 | if sub_entry_type != 1 23 | log sub_entry_name sub_entry_offset sub_entry_size 24 | endif 25 | next j 26 | next i 27 | -------------------------------------------------------------------------------- /moderngroove.bms: -------------------------------------------------------------------------------- 1 | # ModernGroove - Ministry of Sound Edition (PS2) - MGPS2.MGA 2 | 3 | get moderngroove_file filename 4 | 5 | if moderngroove_file != "MGPS2.MGA" 6 | print " whoops " 7 | cleanexit 8 | endif 9 | 10 | get mga_files longlong 11 | for i = 0 < mga_files 12 | get file_offset longlong 13 | get file_size longlong 14 | getdstring file_name 0x30 15 | log file_name file_offset file_size 16 | next i 17 | -------------------------------------------------------------------------------- /motor_toon_grand_prix.bms: -------------------------------------------------------------------------------- 1 | # Early Polyphony Digital archives 2 | # --- 3 | # Motor Toon Grand Prix/Motor Toon Grand Prix 2(PS1) - MTGPX.DAT/MTGPX2.DAT 4 | # Gran Turismo 2000(PS2) - GT2K.VOL 5 | 6 | get dat_size asize 7 | get ext extension 8 | 9 | endian big 10 | if ext == "dat" || ext == "vol" 11 | do 12 | get namesz byte 13 | getdstring name namesz 14 | get offset long 15 | get size long 16 | math offset << 11 17 | if name != "" 18 | log name offset size 19 | else 20 | break 21 | endif 22 | savepos curr_off 23 | while curr_off < dat_size 24 | else 25 | break 26 | endif 27 | -------------------------------------------------------------------------------- /musouorochi2hyper_wiiu_linkdata.bms: -------------------------------------------------------------------------------- 1 | # Musou Orochi 2 Hyper (Wii U) 2 | # Warriors Orochi 3 Hyper (Wii U) - worldwide title of the above, but same game 3 | # --- 4 | # LINKDATA.[IDX+BIN] 5 | # LINKDATA2.[IDX+BIN] 6 | # LINKDATA3.[IDX+BIN] 7 | # --- 8 | # this script covers the "bigfile" format used in the game whose names can be seen above. 9 | # said format has only the barest of minimum in terms of structure: 10 | # two file size values, a file offset value and a flag that says if this file is "compressed" or not. 11 | # if it is, then said file is packed into a format of its own. 12 | # where the file is divided into compressed blocks that must either be decompressed 13 | # using a zlib decompressor that the game uses or through some calcs if said block turns out to not be compressed. 14 | # the latter threw me off a lot of the time so the script had to be more than a bit polished 15 | # to get the "decompression" part to work at all. 16 | # when in doubt, you can apply this script on either the BIN file or the IDX file. 17 | # --- 18 | # this script was tested on the base game files and the patch files. 19 | # the DLC files aren't stored in one of those weird "LINKDATA" files, 20 | # but instead stored across several folders (example - 00c0/DATA) 21 | # and are all bearing the bin extension (example - 00c0/DATA/01642.bin) 22 | 23 | endian big 24 | 25 | get linkdata_name basename 26 | if linkdata_name == "LINKDATA" 27 | callfunction handle_linkdata 1 28 | elif linkdata_name == "LINKDATA2" 29 | callfunction handle_linkdata 1 30 | elif linkdata_name == "LINKDATA3" 31 | callfunction handle_linkdata 1 32 | else 33 | cleanexit 34 | endif 35 | 36 | comtype zlib 37 | 38 | startfunction handle_linkdata 39 | open FDDE "IDX" 0 40 | open FDDE "BIN" 1 41 | math idx_pos = 0 42 | get idx_size asize 0 43 | for i = 0 44 | string temp_name p "%u.bin" i 45 | math do_not_extract = 0 46 | math data_offset = 0 47 | goto idx_pos 0 48 | if idx_pos == idx_size 49 | break 50 | endif 51 | get file_offset longlong 0 52 | get file_size1 longlong 0 53 | get file_size2 longlong 0 54 | get file_is_compressed longlong 0 55 | if file_size1 == file_size2 56 | if file_size2 == 0 57 | math do_not_extract = 1 58 | endif 59 | endif 60 | if do_not_extract != 1 61 | if file_is_compressed != 1 62 | log temp_name file_offset file_size2 1 63 | else 64 | goto file_offset 1 65 | get max_block_size long 1 66 | get chunks long 1 67 | get original_file_size long 1 68 | if original_file_size != 0 69 | xmath last_chunk "chunks - 1" 70 | math remaining_size1 = original_file_size 71 | math remaining_size2 = original_file_size 72 | xmath remaining_size1_modulus "remaining_size1 % max_block_size" 73 | math remaining_size2 - remaining_size1_modulus 74 | xmath data_offset "(chunks * 4) + 12" 75 | math data_offset x 128 76 | math chunk_offset = data_offset 77 | math chunk_offset + file_offset 78 | xmath putvarchr_size "chunks * max_block_size" 79 | putvarchr MEMORY_FILE putvarchr_size 0 80 | log MEMORY_FILE 0 0 81 | math decompressed_chunk_size = 0 82 | append 83 | for j = 0 < chunks 84 | if j = last_chunk 85 | math decompressed_chunk_size = remaining_size1 86 | math remaining_size_modulus = remaining_size1_modulus 87 | else 88 | math decompressed_chunk_size = max_block_size 89 | xmath remaining_size_modulus "remaining_size2 % max_block_size" 90 | endif 91 | get base_chunk_size long 1 92 | if base_chunk_size == remaining_size_modulus 93 | log MEMORY_FILE chunk_offset decompressed_chunk_size 1 94 | else 95 | savepos temp_01 1 96 | goto chunk_offset 1 97 | get compressed_chunk_size long 1 98 | savepos chunk_data_offset 1 99 | clog MEMORY_FILE chunk_data_offset compressed_chunk_size decompressed_chunk_size 1 100 | goto temp_01 1 101 | endif 102 | xmath chunk_size_modulus "base_chunk_size % 128" 103 | xmath chunk_size_subtract "128 - chunk_size_modulus" 104 | math chunk_offset + base_chunk_size 105 | if chunk_size_subtract != 128 106 | math chunk_offset + chunk_size_subtract 107 | endif 108 | math remaining_size1 - max_block_size 109 | math remaining_size2 - max_block_size 110 | next j 111 | append 112 | log temp_name 0 original_file_size MEMORY_FILE 113 | log MEMORY_FILE 0 0 114 | endif 115 | endif 116 | endif 117 | math idx_pos + 32 118 | next i 119 | endfunction 120 | -------------------------------------------------------------------------------- /my_fitness_coach_pak.bms: -------------------------------------------------------------------------------- 1 | # My Fitness Coach (Wii) - *.pak(MRQZ) 2 | # --- 3 | # pak files from this game are mostly 1-2MB in size, sometimes 300-500KB even 4 | 5 | get pak_signature long 6 | if pak_signature != 0x5a51524d # "MRQZ" 7 | cleanexit 8 | endif 9 | get pak_size long 10 | get pak_03 short 11 | get pak_info_offset short 12 | math pak_info_offset + 8 13 | get pak_files long 14 | get pak_data_size long 15 | get pak_07 long 16 | get pak_08 long 17 | xmath pak_header_size "pak_08 - pak_07" 18 | xmath pak_base_offset "pak_info_offset + pak_header_size" 19 | log MEMORY_FILE pak_info_offset pak_header_size 20 | goto 0 MEMORY_FILE 21 | for i = 0 < pak_files 22 | getdstring file_name 0x40 MEMORY_FILE 23 | putarray 0 i file_name 24 | get file_offset long MEMORY_FILE 25 | math file_offset + pak_base_offset 26 | putarray 1 i file_offset 27 | get file_size long MEMORY_FILE 28 | putarray 2 i file_size 29 | get file_04 long MEMORY_FILE 30 | putarray 3 i file_04 31 | next i 32 | for i = 0 < pak_files 33 | getarray file_name 0 i 34 | getarray file_offset 1 i 35 | getarray file_size 2 i 36 | getarray file_04 3 i 37 | log file_name file_offset file_size 38 | next i 39 | -------------------------------------------------------------------------------- /namco_smv.bms: -------------------------------------------------------------------------------- 1 | open FDDE "smv" 0 2 | 3 | get smv_size asize 0 4 | get smv_name basename 0 5 | math smv_current_position = 0 6 | math smv_current_block_size = 0x800 7 | 8 | append 9 | for i = 0 10 | goto smv_current_position 11 | if smv_current_position >= smv_size 12 | break 13 | endif 14 | get smv_next_block_size long 15 | get smv_02 long 16 | get smv_03 long 17 | get smv_04 long 18 | savepos smv_chunk_offset 19 | if smv_04 != 0 20 | xmath smv_03_02 "smv_03 - 0x10" 21 | string smv_vn p "%s.m2v" smv_name 22 | log smv_vn smv_chunk_offset smv_02 23 | math smv_chunk_offset + smv_03_02 24 | string smv_an p "%s.pcm" smv_name 25 | log smv_an smv_chunk_offset smv_04 26 | endif 27 | math smv_current_position + smv_current_block_size 28 | math smv_current_block_size = smv_next_block_size 29 | next i 30 | append 31 | -------------------------------------------------------------------------------- /other_insanities/README.md: -------------------------------------------------------------------------------- 1 | here goes stuff i don't intend to write a script for, among other things. 2 | -------------------------------------------------------------------------------- /other_insanities/nusound.txt: -------------------------------------------------------------------------------- 1 | NuSound middleware documentation (WIP, anyone help!) 2 | 3 | NuSound 1(200?-2006?) uses binary files for pretty much everything, including configuration settings and stream offsets for each sound (albeit somewhat separately), although it may not be the case for some Namco games as it's up to the devs to develop binary files or some other scheme to aid the following formats into playing a sound entry/sound file in-game. 4 | as far as streamed sound formats are concerned, we have: 5 | NPSF(nps extension, for PS2 and PSP platforms) 6 | Cstr(dsp extension, for Gamecube platform) 7 | NXBF(wav extension, for Xbox platform) 8 | and as for sound bank formats, we have: 9 | pbd/phd/p3d(for PS2 and PSP platforms, signed ID is PHDp for phd and P3Dp for p3d) 10 | cbd/chd/c3d(for Gamecube platform, signed ID is CHDp for chd and C3Dp for c3d) 11 | xbd/xhd(for Xbox platform, signed ID is XHDp and notice the lack of "3d" format unlike the previous two) 12 | 13 | sometimes the streamed files that take advantage of these formats are concatenated into one(or more) big file(s) while the necessary info for reading these files (including sound banks) are around somewhere the game invokes a streamed sound (source for that sound can come from either a standalone format or a sound bank) into in-game. in the case of Xbox game Breakdown, these streamed sound files are built into an entire file archival format that has all info needed to load these files at which point the game will invoke those formats so all these sounds can be played in-game anyway. 14 | 15 | NuSound 2(2005-201?) uses its own nub file format for sound banks and the rest are all binary files with their own formats for configuration settings. 16 | as a consequence of this, many other files that rely on nub files are invoked into in-game for real-time playback. 17 | audio codec usage in nub is odd. sometimes, a sound entry might have a codec that turns out to have its own header into related to the sound entry using that codec in question(XMA, big-endian PCM, VAG). sometimes, a sound entry might have an entire full header designed for use in a file format in case of using another codec(IDSP, RIFF AT3, BNSF is14). sometimes, a sound entry might even be sequenced or even contain anything at all for some reason(codec number 05). 18 | 19 | NuSound 3(2011-present) uses NUS3 chunked file format for any situation, including configuration settings(nus3conf, nus3conf3d) and sound banks(nus2, nus3bank, nus3audio) 20 | this NUS3 audio system is home to at least two formats: configuration file(nus3conf, nus3conf3d) and sound bank file(nus3bank, nus3audio) respectively. 21 | naturally, only the "sound bank file" format is allowed to store several formats depending on which codec a single sound entry uses within that file. there are a few common formats that can accept any codec on its wake: 22 | RIFF - Resource Interchange File Format, derived from EA's Interchangeable File Format. NUS3 audio system uses its WAVE extension. 23 | IFF - Interchangeable File Format, what RIFF has been inspired by. file always starts with FORM chunk and can handle many file types as much as it wants to. NUS3 audio system uses its AIFF extension. 24 | however, turns out some Bandai Namco developers designed some codec-exclusive formats for use in the company's proprietary sound bank containers that use this NUS3 format (both the NUS3 format and some of these below-listed formats documented through vgmstream code), here is a rundown of some of them: 25 | BNSF - oh yes, this one uses two audio codecs(IS14 and IS22, respectively) and an additional mode for one codec. known extension varies per game; sometimes it's either is14/is22 or spsis14/spsis22 depending on whether or not either codec is there. 26 | -------------------------------------------------------------------------------- /pants_pac.bms: -------------------------------------------------------------------------------- 1 | # Pipo Saru 2001 - PANTS.PAC 2 | 3 | open FDDE "pac" 0 4 | 5 | getdstring pac_title 32 6 | get pac_tocoff1 long 7 | get pac_tocsize1 long 8 | get pac_03 long 9 | 10 | math pac_tocoff1 << 11 11 | math pac_tocsize1 << 11 12 | 13 | log MEMORY_FILE10 pac_tocoff1 pac_tocsize1 14 | 15 | for 16 | get pac_general_data line MEMORY_FILE10 17 | if pac_general_data == "!-------- END --------!" 18 | break 19 | else 20 | string pac_general_data R "," " " 21 | string pac_full_data S pac_general_data pac_fname pac_foffset pac_fsize 22 | log pac_fname pac_foffset pac_fsize 23 | endif 24 | next 25 | -------------------------------------------------------------------------------- /polyphony_ps2vol.bms: -------------------------------------------------------------------------------- 1 | open FDDE "vol" 0 2 | get vol_size asize 3 | 4 | math name_quirks = 0 5 | get vol_sign long 6 | if vol_sign == 0xacb990ad 7 | math name_quirks = 1 8 | print "\n hold on, this script will analyze the archive itself based on a 4-byte sign alongside its 4-byte number just so it can handle the whole extraction/reimport process. \n don't worry this script won't scan the entire archive for just two 4-byte values, but you do have to wait until the script can extract the files for you. " 9 | savepos temp_01 10 | goto 0 11 | math vol_ver = 0 12 | math c_01 = 0 13 | do 14 | savepos temp_02 15 | get vol_check_01 long 16 | get vol_check_02 long 17 | if vol_check_01 == 0xacb990ad 18 | math c_01 + 1 19 | putarray c_01 0 temp_02 20 | if vol_check_02 == 0x00020002 21 | math vol_ver = 1 22 | endif 23 | if vol_check_02 == 0x00030001 24 | math vol_ver = 2 25 | endif 26 | endif 27 | math temp_02 += 0x800 28 | goto temp_02 29 | while temp_02 != 0x2000000 30 | goto temp_01 31 | print "\n right... parsing vol info now. \n" 32 | elif vol_sign == 0x53466f52 33 | math vol_ver = 1 34 | print " \n found .vol file with RoFS sign. \n parsing vol info now." 35 | putarray 1 0 0 36 | else 37 | string unknown_vol_sign p "0x%08x" vol_sign 38 | print "\n unknown VOL sign - %unknown_vol_sign% \n find me(AnonBaiter) at ZenHAX or some github repo of mine if you want. " 39 | cleanexit 40 | endif 41 | 42 | if vol_ver = 1 43 | getarray vol_offset 1 0 44 | goto vol_offset 45 | get vol_sign_01 long 46 | get min_ver short 47 | get max_ver short 48 | get header_size long 49 | get info_size long 50 | get name_size long 51 | savepos info_offset 52 | xmath info_size_in_memory "info_size - info_offset" 53 | log MEMORY_FILE info_offset info_size_in_memory 54 | math full_count = info_size_in_memory 55 | for pos_01 = 0 < full_count 56 | savepos pos_01 MEMORY_FILE 57 | get entry_01 long MEMORY_FILE 58 | if entry_01 != 0 59 | xmath entry_01_01 "(entry_01 >> 24) & 0xff" 60 | putarray 1 0 entry_01_01 61 | xmath entry_01_02 "entry_01 & 0xffffff" 62 | putarray 1 0 entry_01_02 63 | set entry_02 string "" 64 | goto entry_01_02 65 | if name_quirks = 0 66 | get entry_02 string 67 | elif name_quirks = 1 68 | for x = 0 69 | get string_byte byte 70 | if string_byte = 0xff 71 | break 72 | else 73 | math string_byte ^ -1 74 | math string_byte & 0xff 75 | string string_byte = string_byte 76 | string entry_02 + string_byte 77 | endif 78 | next x 79 | endif 80 | putarray 1 0 entry_02 81 | if entry_01_01 == 0 82 | get entry_03 long MEMORY_FILE 83 | xmath file_offset "entry_03 << 11" 84 | get entry_04 long MEMORY_FILE 85 | math file_size == entry_04 86 | string temp_name p "normal\" 87 | log temp_name file_offset file_size 88 | elif entry_01_01 == 1 89 | get entry_03 long MEMORY_FILE 90 | putarray 1 0 entry_03 91 | for j = 0 < entry_03 92 | get entry_03_01 long MEMORY_FILE 93 | putarray 1 0 entry_03_01 94 | next j 95 | elif entry_01_01 == 2 96 | get entry_03 long MEMORY_FILE 97 | xmath file_offset "entry_03 << 11" 98 | get entry_04 long MEMORY_FILE 99 | math original_file_size_01 == entry_04 100 | get entry_05 long MEMORY_FILE 101 | math compressed_file_size_01 == entry_05 102 | xmath raw_deflate_size "entry_05 - 8" 103 | goto file_offset 104 | for cc = 1 <= 2 105 | get compressed_sign byte 106 | if cc = 1 107 | if compressed_sign == 0x1f 108 | math comp_type = 1 109 | elif compressed_sign == 0xc5 110 | math comp_type = 2 111 | endif 112 | elif cc = 2 113 | if compressed_sign == 0x8b 114 | math comp_type = 1 115 | elif compressed_sign == 0xee 116 | math comp_type = 2 117 | endif 118 | endif 119 | next cc 120 | if comp_type = 1 121 | comtype gzip 122 | elif comp_type = 2 123 | comtype deflate_noerror 124 | goto file_offset 125 | get deflate_sign long 126 | math deflate_sign ~ deflate_sign 127 | get original_file_size_02 long 128 | math original_file_size_02 ~ original_file_size_02 129 | math file_offset + 8 130 | endif 131 | string temp_name p "compressed\" 132 | clog temp_name file_offset raw_deflate_size original_file_size_01 133 | endif 134 | else 135 | break 136 | endif 137 | next 138 | endif 139 | if vol_ver == 2 140 | getarray vol_offset 2 0 141 | goto vol_offset 142 | get vol_sign_02 long 143 | get min_ver short 144 | get max_ver short 145 | get cycles_01 long 146 | get cycles_02 long 147 | get cycles_03 short 148 | get file_info_chunks short 149 | xmath base_offset "(vol_offset >> 11) + ((cycles_01 && 0x800) >> 11)" 150 | putarray 0 0 base_offset 151 | xmath encrypted_offset "vol_offset + 0x40" 152 | goto encrypted_offset 153 | math decoded_value = 0 154 | math z1 = 1 155 | math z2 = 0 156 | for i = 0 <= file_info_chunks 157 | math value_01 = 0x14AC327A 158 | get file_value long 159 | math value_01 * z1 160 | xmath decoded_value "(file_value ^ value_01) & 0xffffffff" 161 | putarray 1 z2 decoded_value 162 | math z1 + 1 163 | math z2 + 1 164 | next i 165 | comtype deflate_noerror 166 | math entry_index = 0 167 | math actual_entry_index = 0 168 | for j = 0 < file_info_chunks 169 | getarray info_offset 1 j 170 | math archive_info_chunk_size = 0 171 | math j + 1 172 | getarray next_offset 1 j 173 | math j - 1 174 | xmath info_size "next_offset - info_offset" 175 | xmath info_off_02 "info_offset + vol_offset" 176 | math original_info_size = 0x800 177 | clog MEMORY_FILE info_off_02 info_size original_info_size 178 | filexor 0x55 179 | get chunk_type short MEMORY_FILE 180 | get chunk_entries short MEMORY_FILE 181 | math chunk_entries >> 1 182 | get chunk_number_01 long MEMORY_FILE 183 | get chunk_number_02 long MEMORY_FILE 184 | if chunk_type == 0 185 | for m = 0 < chunk_entries 186 | set entry_02 string "" 187 | get entry_01 long MEMORY_FILE 188 | xmath entry_01_01 "((entry_01 >> 24) & 0xff) | (((entry_01 >> 16) & 0xff) << 8) | (((entry_01 >> 8) & 0xff) << 16) | ((entry_01 & 0xff) << 24)" 189 | putarray 11 entry_index entry_01_01 190 | for 191 | get string_byte byte MEMORY_FILE 192 | if string_byte >= 0 && string_byte <= 2 193 | goto -1 MEMORY_FILE SEEK_CUR 194 | break 195 | else 196 | string string_byte = string_byte 197 | string entry_02 + string_byte 198 | endif 199 | next 200 | padding 4 MEMORY_FILE 201 | putarray 12 entry_index entry_02 202 | get entry_03 byte MEMORY_FILE 203 | putarray 13 entry_index entry_03 204 | get entry_04 long MEMORY_FILE 205 | putarray 14 entry_index entry_04 206 | if entry_03 == 1 207 | get entry_05 time MEMORY_FILE 208 | putarray 15 entry_index entry_05 209 | get entry_06 long MEMORY_FILE 210 | putarray 16 entry_index entry_06 211 | elif entry_03 == 2 212 | get entry_05 time MEMORY_FILE 213 | putarray 15 entry_index entry_05 214 | get entry_06 long MEMORY_FILE 215 | putarray 16 entry_index entry_06 216 | get entry_07 long MEMORY_FILE 217 | putarray 17 entry_index entry_07 218 | endif 219 | getdstring padding_02 3 MEMORY_FILE 220 | math entry_index + 1 221 | next m 222 | savepos archive_info_chunk_size MEMORY_FILE 223 | for k1 = 0 224 | get check_number short MEMORY_FILE 225 | if check_number == archive_info_chunk_size 226 | for m = 0 < chunk_entries 227 | get entry_08 short MEMORY_FILE 228 | putarray 18 entry_index entry_08 229 | get entry_09 short MEMORY_FILE 230 | putarray 19 entry_index entry_09 231 | next m 232 | break 233 | endif 234 | next k1 235 | endif 236 | filexor "" 237 | next j 238 | math total_entries = entry_index 239 | for i = 0 < total_entries 240 | getarray entry_point 11 i 241 | getarray entry_name 12 i 242 | getarray entry_type 13 i 243 | getarray entry_position 14 i 244 | getarray entry_name_offset 18 i 245 | getarray entry_name_size 19 i 246 | if entry_type != 0 247 | xmath file_offset "(entry_position + base_offset) << 11" 248 | getarray file_timestamp 15 i 249 | endif 250 | if entry_type == 1 251 | getarray file_size 16 i 252 | string temp_name p "normal\" 253 | log temp_name file_offset file_size 254 | elif entry_type == 2 255 | getarray compressed_file_size 16 i 256 | xmath raw_deflate_size "compressed_file_size - 8" 257 | getarray original_file_size_01 17 i 258 | goto file_offset 259 | get deflate_sign long 260 | math deflate_sign ~ deflate_sign 261 | get original_file_size_02 long 262 | math original_file_size_02 ~ original_file_size_02 263 | math file_offset + 8 264 | string temp_name p "compressed\" 265 | clog temp_name file_offset raw_deflate_size original_file_size_01 266 | endif 267 | next i 268 | endif 269 | -------------------------------------------------------------------------------- /reflections_img.bms: -------------------------------------------------------------------------------- 1 | # Ubisoft Reflections - *.img/*.L## 2 | # --- 3 | # Stuntman (PS2) 4 | # Driv3r (PS2, Xbox) 5 | # Driver: Parallel Lines (PS2, Xbox) 6 | 7 | math external = 0 8 | get img_name basename 9 | get img_size asize 10 | get img_sign long 11 | get img_files long 12 | get hardcoded_file_info_hash long 13 | math initial_file_info_position = 0 14 | math img_ver = 0 15 | if img_sign == 0x32474d49 # IMG2 (Stuntman, from second demo release to final USA release) 16 | xmath img_archive_info_size "img_files * 0x38" 17 | math initial_file_info_position = 0x0c 18 | math img_ver = 1 19 | elif img_sign == 0x33474d49 # IMG3 (Stuntman, final Europe release only) 20 | get img_archive_info_size long 21 | math initial_file_info_position = 0x10 22 | math img_ver = 2 23 | elif img_sign == 0x34474d49 # IMG4 (starting with Driv3r) 24 | get img_archive_info_size long 25 | math initial_file_info_position = 0x10 26 | math img_ver = 3 27 | endif 28 | xmath img_is_xbox "(((img_archive_info_size + initial_file_info_position) >> 11) + 1) << 11" 29 | # (todo) this is too rough for my tastes 30 | if img_size = img_is_xbox 31 | math external = 1 32 | endif 33 | 34 | goto initial_file_info_position 35 | if img_ver = 1 36 | math init_hash_number = 0x2eaa508 37 | for i = 0 < img_archive_info_size 38 | get byte_to_calc byte 39 | math init_hash_number + byte_to_calc 40 | next i 41 | else 42 | math init_hash_number = 0 43 | for i = 0 < img_archive_info_size 44 | get byte_to_calc byte 45 | math init_hash_number + byte_to_calc 46 | next i 47 | putarray 0 0 init_hash_number 48 | endif 49 | /* 50 | math final_hash_number = init_hash_number 51 | if final_hash_number != hardcoded_file_info_hash 52 | break 53 | endif 54 | */ 55 | goto initial_file_info_position 56 | log MEMORY_FILE 0 img_archive_info_size 57 | if img_ver = 1 58 | math init_dec_number = 0x1b 59 | for i = 0 < img_archive_info_size 60 | get enc_byte byte 61 | math enc_byte - init_dec_number 62 | put enc_byte byte MEMORY_FILE 63 | math init_dec_number + 0x0b 64 | math init_dec_number & 0xff 65 | next i 66 | goto 0 MEMORY_FILE 67 | for i = 0 < img_files 68 | getdstring file_name 0x30 MEMORY_FILE 69 | get file_offset long MEMORY_FILE 70 | get file_size long MEMORY_FILE 71 | if img_size <= 0xffefffff 72 | math file_offset << 11 73 | log file_name file_offset file_size 74 | elif img_size == 0xfff00000 75 | callfunction special_file_handle_within_split_img_files 1 76 | endif 77 | next i 78 | elif img_ver >= 2 79 | math init_number_01 = 0x1b 80 | math init_number_02 = 0 81 | for i = 0 < img_archive_info_size 82 | get enc_byte byte 83 | xmath first_step "init_number_02 & 0x1f" 84 | math enc_byte - init_number_01 85 | put enc_byte byte MEMORY_FILE 86 | if first_step >= 7 87 | math init_number_01 + 0x0b 88 | else 89 | math init_number_01 + 0x15 90 | endif 91 | math init_number_01 & 0xff 92 | math init_number_02 + 1 93 | next i 94 | goto 0 MEMORY_FILE 95 | for i = 0 < img_files 96 | if img_ver = 2 97 | get file_name_offset long MEMORY_FILE 98 | savepos img_temp_position MEMORY_FILE 99 | goto file_name_offset MEMORY_FILE 100 | get file_name string MEMORY_FILE 101 | goto img_temp_position MEMORY_FILE 102 | get file_offset long MEMORY_FILE 103 | get file_size long MEMORY_FILE 104 | if img_size == 0xfff00000 105 | callfunction special_file_handle_within_split_img_files 1 106 | else 107 | math file_offset << 11 108 | log file_name file_offset file_size 109 | endif 110 | elif img_ver = 3 111 | get hardcoded_file_name_hash long MEMORY_FILE 112 | get file_02 long MEMORY_FILE 113 | get file_size long MEMORY_FILE 114 | string temp_name p "%08x" hardcoded_file_name_hash 115 | if external = 0 116 | if img_size == 0xfff00000 117 | callfunction special_file_handle_within_split_img_files 1 118 | else 119 | xmath file_offset "file_02 << 11" 120 | log temp_name file_offset file_size 121 | endif 122 | elif external = 1 123 | xmath file_offset "((file_02 >> 8) & 0xffffff) << 11" 124 | xmath img_layer_number_01 "(file_02 >> 4) & 0x0f" 125 | xmath img_layer_number_02 "file_02 & 0x0f" 126 | string img_layer_name p "%s.L%d%d" img_name img_layer_number_01 img_layer_number_02 127 | open FDSE img_layer_name 1 128 | log temp_name file_offset file_size 1 129 | endif 130 | endif 131 | next i 132 | endif 133 | 134 | startfunction special_file_handle_within_split_img_files 135 | xmath img_reduced_size "0xfff00000 >> 11" 136 | if img_ver = 3 137 | math file_offset == file_02 138 | endif 139 | xmath img_number "file_offset / img_reduced_size" 140 | if img_number == 0 141 | string img_layer_name p "%s.img" img_name 142 | else 143 | math img_number - 1 144 | string img_layer_name p "%s.im%d" img_name img_number 145 | endif 146 | open FDSE img_layer_name 1 147 | xmath file_offset_per_layer "(file_offset % img_reduced_size) << 11" 148 | xmath test_01 "(file_offset_per_layer >> 11) + (file_size >> 11)" 149 | xmath total_number_of_chunks_per_file_within_split_archive "((file_offset_per_layer >> 11) + (file_size >> 11)) / img_reduced_size" 150 | if total_number_of_chunks_per_file_within_split_archive == 0 151 | if img_ver <= 2 152 | log file_name file_offset_per_layer file_size 1 153 | elif img_ver = 3 154 | log temp_name file_offset_per_layer file_size 1 155 | endif 156 | else 157 | math last_j = total_number_of_chunks_per_file_within_split_archive 158 | math current_img_layer = img_number 159 | append 160 | for j = 0 <= total_number_of_chunks_per_file_within_split_archive 161 | math chunked_file_offset_within_split_archive = 0 162 | math chunked_file_size_within_split_archive = 0 163 | if current_img_layer == 0 164 | string temp_load p "%s.img" img_name 165 | else 166 | math alternative_img_layer = current_img_layer 167 | math alternative_img_layer - 1 168 | string temp_load p "%s.im%d" img_name alternative_img_layer 169 | endif 170 | open FDSE temp_load 2 171 | if j = 0 172 | math chunked_file_offset_within_split_archive = file_offset_per_layer 173 | xmath chunked_file_size_within_split_archive "(((test_01 - ((total_number_of_chunks_per_file_within_split_archive - 1) * img_reduced_size)) - (test_01 - ((total_number_of_chunks_per_file_within_split_archive) * img_reduced_size))) - (file_offset_per_layer >> 11)) << 11" 174 | elif j = last_j 175 | xmath chunked_file_size_within_split_archive "((test_01 - ((total_number_of_chunks_per_file_within_split_archive) * img_reduced_size)) << 11) + (file_size % (1 << 11))" 176 | else 177 | math chunked_file_size_within_split_archive = img_size 178 | endif 179 | if img_ver <= 2 180 | log file_name chunked_file_offset_within_split_archive chunked_file_size_within_split_archive 2 181 | elif img_ver = 3 182 | log temp_name chunked_file_offset_within_split_archive chunked_file_size_within_split_archive 2 183 | endif 184 | math current_img_layer + 1 185 | next j 186 | append 187 | endif 188 | endfunction 189 | -------------------------------------------------------------------------------- /rmdp.bms: -------------------------------------------------------------------------------- 1 | # Remedy Entertainment - *.bin/*.rmdp 2 | 3 | get remedy_extension extension 4 | open FDDE "rmdp" 1 5 | 6 | math 32bit_minus_one = 0xffffffff 7 | math 64bit_minus_one = 0xffffffffffffffff 8 | 9 | if remedy_extension == "bin" 10 | get bin_endian_type byte 11 | if bin_endian_type == 0 12 | endian little 13 | elif bin_endian_type == 1 14 | endian big 15 | endif 16 | get bin_version long 17 | get bin_directories long 18 | get bin_files long 19 | if bin_version >= 7 20 | get bin05 longlong 21 | endif 22 | get bin_name_size long 23 | getdstring bin_dummy_data 0x80 24 | if bin_version <= 7 25 | math sec_size_per_dir = 28 26 | elif bin_version >= 8 27 | math sec_size_per_dir = 48 28 | endif 29 | if bin_version == 2 30 | math sec_size_per_file = 40 31 | elif bin_version == 7 32 | math sec_size_per_file = 48 33 | elif bin_version >= 8 34 | math sec_size_per_file = 60 35 | endif 36 | if bin_version == 2 37 | math init_bin_hdr_size = 0x91 38 | elif bin_version == 7 39 | xmath init_bin_hdr_size "0x99 + 0x1c" 40 | elif bin_version >= 8 41 | xmath init_bin_hdr_size "0x99 + 0x30" 42 | endif 43 | xmath bin_directory_entries_sector_size "bin_directories * sec_size_per_dir" 44 | xmath bin_file_entries_sector_size "bin_files * sec_size_per_file" 45 | xmath bin_name_offset "bin_directory_entries_sector_size + bin_file_entries_sector_size + init_bin_hdr_size" 46 | for one = 0 < bin_directories 47 | if bin_version <= 7 48 | get directory_01 long 49 | putarray 01 one directory_01 50 | get directory_02 long 51 | putarray 02 one directory_02 52 | get directory_03 long 53 | putarray 03 one directory_03 54 | get directory_04 long 55 | putarray 04 one directory_04 56 | get directory_05 long 57 | putarray 05 one directory_05 58 | get directory_06 long 59 | putarray 06 one directory_06 60 | get directory_07 long 61 | putarray 07 one directory_07 62 | elif bin_version >= 8 63 | get directory_01 long 64 | putarray 01 one directory_01 65 | get directory_02 longlong 66 | putarray 02 one directory_02 67 | get directory_03 longlong 68 | putarray 03 one directory_03 69 | get directory_04 long 70 | putarray 04 one directory_04 71 | get directory_05 longlong 72 | putarray 05 one directory_05 73 | get directory_06 longlong 74 | putarray 06 one directory_06 75 | get directory_07 longlong 76 | putarray 07 one directory_07 77 | endif 78 | next one 79 | savepos temp_01 80 | for one = 0 < bin_directories 81 | getarray directory_05 05 one 82 | if directory_05 == 32bit_minus_one || directory_05 == 64bit_minus_one 83 | putarray 08 one "" 84 | # alternatively i could've just put in "d:\data" but whatevs 85 | else 86 | math directory_05 + bin_name_offset 87 | goto directory_05 88 | get directory_08 string 89 | putarray 08 one directory_08 90 | endif 91 | next one 92 | goto temp_01 93 | for two = 0 < bin_files 94 | if bin_version == 2 95 | get file_01 long 96 | putarray 11 two file_01 97 | get file_02 long 98 | putarray 12 two file_02 99 | get file_03 long 100 | putarray 13 two file_03 101 | get file_04 longlong 102 | putarray 14 two file_04 103 | get file_05 longlong 104 | putarray 15 two file_05 105 | get file_06 longlong 106 | putarray 16 two file_06 107 | get file_07 long 108 | putarray 17 two file_07 109 | elif bin_version == 7 110 | get file_01 long 111 | putarray 11 two file_01 112 | get file_02 long 113 | putarray 12 two file_02 114 | get file_03 long 115 | putarray 13 two file_03 116 | get file_04 long 117 | putarray 14 two file_04 118 | get file_05 long 119 | putarray 15 two file_05 120 | get file_06 longlong 121 | putarray 16 two file_06 122 | get file_07 longlong 123 | putarray 17 two file_07 124 | get file_08 long 125 | putarray 18 two file_08 126 | get file_09 time64 127 | putarray 19 two file_09 128 | elif bin_version >= 8 129 | get file_01 long 130 | putarray 11 two file_01 131 | get file_02 longlong 132 | putarray 12 two file_02 133 | get file_03 long 134 | putarray 13 two file_03 135 | get file_04 longlong 136 | putarray 14 two file_04 137 | get file_05 longlong 138 | putarray 15 two file_05 139 | get file_06 longlong 140 | putarray 16 two file_06 141 | get file_07 longlong 142 | putarray 17 two file_07 143 | get file_08 long 144 | putarray 18 two file_08 145 | get file_09 time64 146 | putarray 19 two file_09 147 | endif 148 | next two 149 | savepos temp_02 150 | for two = 0 < bin_files 151 | if bin_version == 2 152 | getarray file_11 14 two 153 | elif bin_version >= 7 154 | getarray file_11 15 two 155 | endif 156 | math file_11 + bin_name_offset 157 | goto file_11 158 | get file_12 string 159 | if bin_version == 2 160 | putarray 18 two file_12 161 | elif bin_version >= 7 162 | putarray 20 two file_12 163 | endif 164 | next two 165 | goto temp_02 166 | for d1 = 0 < bin_directories 167 | math current_number = d1 168 | math current_string_index = 0 169 | callfunction array_listing_of_directory_entry_within_sector 1 170 | putarray 101 current_string_index directory_name_string 171 | if parent_directory_number != 32bit_minus_one && parent_directory_number != 64bit_minus_one 172 | for 173 | math current_string_index + 1 174 | math current_number = parent_directory_number 175 | callfunction array_listing_of_directory_entry_within_sector 1 176 | putarray 101 current_string_index directory_name_string 177 | if parent_directory_number == 32bit_minus_one || parent_directory_number == 64bit_minus_one 178 | break 179 | endif 180 | next 181 | math last_string_index = current_string_index 182 | math reordered_string_index = 0 183 | set full_directory_name string "" 184 | for 185 | getarray current_string_key 101 last_string_index 186 | if reordered_string_index >= 2 187 | string full_directory_name + "\" 188 | endif 189 | string full_directory_name + current_string_key 190 | if last_string_index != 0 191 | math last_string_index - 1 192 | math reordered_string_index + 1 193 | else 194 | break 195 | endif 196 | next 197 | else 198 | set full_directory_name string "" 199 | endif 200 | putarray 102 d1 full_directory_name 201 | next d1 202 | for f1 = 0 < bin_files 203 | math current_number = f1 204 | callfunction array_listing_of_file_entry_within_sector 1 205 | getarray full_directory_name 102 directory_base_number 206 | string full_file_name p "%s\%s" full_directory_name file_name_string 207 | log full_file_name file_offset file_size 1 208 | next f1 209 | elif remedy_extension == "xml" 210 | # SOON(TM) 211 | elif remedy_extension == "packmeta" 212 | # SOON(TM) 213 | elif remedy_extension == "rmdp" 214 | print " \n obviously, an .rmdp file cannot extract itself. " 215 | cleanexit 216 | endif 217 | 218 | startfunction array_listing_of_directory_entry_within_sector 219 | getarray directory_name_hash 01 current_number 220 | getarray neighbor_directory_number 02 current_number 221 | getarray parent_directory_number 03 current_number 222 | getarray directory_04 04 current_number # this one is just dummy leftover data from whatever it is for all i care 223 | getarray directory_name_offset 05 current_number 224 | getarray incoming_directory_number 06 current_number 225 | getarray base_file_number 07 current_number 226 | getarray directory_name_string 08 current_number 227 | endfunction 228 | 229 | startfunction array_listing_of_file_entry_within_sector 230 | if bin_version == 2 231 | getarray file_01 11 current_number 232 | getarray next_file_number 12 current_number 233 | getarray directory_base_number 13 current_number 234 | getarray file_name_offset 14 current_number 235 | getarray file_offset 15 current_number 236 | getarray file_size 16 current_number 237 | getarray file_07 17 current_number 238 | getarray file_name_string 18 current_number 239 | elif bin_version >= 7 240 | getarray file_01 11 current_number 241 | getarray next_file_number 12 current_number 242 | getarray directory_base_number 13 current_number 243 | getarray file_04 14 current_number 244 | getarray file_name_offset 15 current_number 245 | getarray file_offset 16 current_number 246 | getarray file_size 17 current_number 247 | getarray file_08 18 current_number 248 | getarray file_timestamp 19 current_number 249 | getarray file_name_string 20 current_number 250 | endif 251 | endfunction 252 | -------------------------------------------------------------------------------- /scimitar[new_version]/scimitar_new.bms: -------------------------------------------------------------------------------- 1 | # Ubisoft - *.forge 2 | # --- 3 | # Assassin's Creed (PlayStation 3, Xbox 360) - version 0x19 4 | # Assassin's Creed: Director's Cut (Windows Vista) - version 0x19 5 | # Shaun White Snowboarding (PlayStation 3, Xbox 360, Windows Vista) - version 0x1a 6 | # Prince of Persia (PlayStation 3, Xbox 360, Windows Vista) - version 0x1a 7 | 8 | include "scimitar_compressed_container.bms" 9 | 10 | get scm_name filename 11 | idstring "scimitar\0" 12 | get scm_ver long 13 | get scm_info_off longlong 14 | get scm_03 long 15 | get scm_04 long 16 | /* 17 | if scm_ver < 0x17 18 | getdstring scm_05 1 19 | endif 20 | math scm_05 = 0 21 | */ 22 | 23 | goto scm_info_off 24 | get i01 long 25 | get i02 long 26 | if i02 != 1 27 | print " more tabs are here " 28 | cleanexit 29 | endif 30 | get i03 long 31 | get i04 long 32 | get i05 long 33 | get i06 long 34 | get i07 long 35 | get i08 long 36 | get i09 longlong 37 | goto i09 38 | for i = 0 < i02 39 | get ti01 long # param_1 40 | get ti02 long # param_1 + 4 41 | get ti03 longlong # param_1 + 8 42 | get ti07 longlong # param_1 + 0x10 43 | xmath ti07_1 "ti08 & 0xffffffff" 44 | xmath ti07_2 "(ti08 >> 32) & 0xffffffff" 45 | get ti08 longlong # param_1 + 0x18 46 | xmath ti08_1 "ti08 & 0xffffffff" 47 | xmath ti08_2 "(ti08 >> 32) & 0xffffffff" 48 | get ti04 longlong # param_1 + 0x20 49 | get ti05 long # param_1 + 0x28 50 | get ti06 long # param_1 + 0x2c 51 | # (todo) handle ti04 and ti05 52 | savepos temp_01 53 | for j1 = 0 < ti01 54 | math alt_mode = 0 55 | goto ti03 56 | get fiwt01 longlong 57 | get fiwt02 long 58 | get fiwt03 long 59 | math ti03 + 0x10 60 | goto fiwt01 61 | getdstring is_filedata 8 62 | if is_filedata != "FILEDATA" 63 | break 64 | endif 65 | getdstring fd_n1 0x80 66 | getdstring fd_n2 0xff 67 | get fd03 long 68 | get fd04 long 69 | get fd05 longlong 70 | get fd06 long 71 | get fd07 long 72 | get fd08 long 73 | get fd09 long 74 | get fd10 long 75 | get fd11 long 76 | get fd12 long 77 | get fd13 byte 78 | get fd14 long 79 | savepos fd_o 80 | get fd_sign long 81 | if fd_sign != 0 82 | if fd_sign == 0x00011b01 83 | string temp_name + ".bao" 84 | elif fd_sign == 0x10001f02 85 | string temp_name + ".sbao" 86 | elif fd_sign == 0x99fa0410 87 | math alt_mode = 1 88 | elif fd_sign == 0x57fbaa33 89 | math alt_mode = 1 90 | else 91 | print " unidentified file signature. " 92 | # what that supposed to mean 93 | endif 94 | endif 95 | if alt_mode != 1 96 | string temp_name p "%u/%08x/%08x" i fd12 fd03 97 | log temp_name fd_o fd04 98 | else 99 | string temp_name p "%u/%08x/[%s]%08x" i fd12 fd_n1 fd03 100 | math container_offset = fd_o 101 | math container_passes = 2 102 | callfunction read_container 1 103 | endif 104 | next j1 105 | goto temp_01 106 | next i 107 | 108 | /* 109 | get info_02 longlong 110 | get info_03 longlong 111 | get max_files long 112 | get info_04 long 113 | get info_05 longlong 114 | goto info_05 115 | get info_06 long 116 | get info_07 long 117 | get info_08 longlong 118 | get info_09 longlong 119 | get info_10 long 120 | get info_11 long 121 | get info_12 longlong 122 | get info_13 longlong 123 | goto info_08 124 | for i2 = 0 < max_files 125 | get file_01 longlong 126 | putarray 0 i2 file_01 127 | get file_02 long 128 | putarray 1 i2 file_02 129 | get file_03 long 130 | putarray 2 i2 file_03 131 | next i2 132 | goto info_12 133 | for i3 = 0 < max_files 134 | get file_04 long 135 | putarray 3 i3 file_04 136 | get file_05 long 137 | putarray 4 i3 file_05 138 | get file_06 long 139 | putarray 5 i3 file_06 140 | get file_07 longlong 141 | putarray 6 i3 file_07 142 | get file_08 longlong 143 | putarray 7 i3 file_08 144 | get file_09 long 145 | putarray 8 i3 file_09 146 | get file_10 long 147 | putarray 9 i3 file_10 148 | get file_11 long 149 | putarray 10 i3 file_11 150 | get file_12 time 151 | putarray 11 i3 file_12 152 | getdstring file_13 0x80 153 | putarray 12 i3 file_13 154 | get file_13 longlong 155 | putarray 13 i3 file_13 156 | get file_14 longlong 157 | putarray 14 i3 file_14 158 | next i3 159 | 160 | for i4 = 0 < max_files 161 | getarray file_offset 0 i4 162 | goto file_offset 163 | getdstring is_filedata 8 164 | if is_filedata != "FILEDATA" 165 | break 166 | endif 167 | getdstring init_name 0x80 168 | getdstring alt_name 0xff 169 | get filedata01 long 170 | get filedata02 long 171 | get filedata03 longlong 172 | get filedata04 long 173 | get filedata05 long 174 | get filedata06 long 175 | get filedata07 long 176 | get filedata08 long 177 | get filedata09 long 178 | get filedata10 long 179 | getdstring filedata11 1 180 | get filedata12 long 181 | next i4 182 | 183 | for i5 = 0 < files 184 | getarray physical_file_offset 27 i5 185 | getarray file_id 1 i5 186 | getarray file_size 2 i5 187 | getarray file_name 12 i5 188 | math container_offset == physical_file_offset 189 | math container_passes = 2 190 | callfunction read_container 1 191 | if container_read != 1 192 | log file_name physical_file_offset file_size 193 | endif 194 | next i5 195 | */ 196 | -------------------------------------------------------------------------------- /scimitar_alt.bms: -------------------------------------------------------------------------------- 1 | # Ubisoft Montreal - "scimitar" archive(.forge) 2 | # First used in Assassin`s Creed(PS3, XB0X360, PC). 3 | # ---------------------------------------------- 4 | # Notes: 5 | # The files that start with the \x33\xaa\xfb\x57\x99\xfa\x04\x10 or \x10\x04\xfa\x99\x57\xfb\xaa\x33 sign 6 | # are the ones that hold all the compressed and decompressed data. 7 | # They usually have two files each(one for listing the hashes and the sizes and the other as an achive in itself). 8 | # 9 | # The compressed files need to be decompressed by using a separate script(scimitar_compressed.bms), which 10 | # in itself is based around aluigi's original script(assassins_creed2.bms). 11 | 12 | ### config 13 | 14 | set ADD_COMPRESSED_EXTENSION long 1 15 | 16 | ###################### 17 | 18 | get FORGE_NAME basename 19 | 20 | idstring "scimitar\x00" 21 | get VER long 22 | get INFO_OFF long 23 | get DUMMY3 long 24 | get DUMMY4 long 25 | get DUMMY5 long 26 | get DUMMY6 long 27 | 28 | goto INFO_OFF 29 | 30 | 31 | #base header 32 | get TOTAL_FILES long 33 | get TOTAL_UNKNOWN long #version? 34 | get DUMMY9 long #0 35 | if VER >= 0x1b 36 | get DUMMY10 longlong 37 | else 38 | get DUMMY10 long #0 39 | endif 40 | get DUMMY11 longlong #-1 41 | get CHUNK_FILES_MAX long # 5000 42 | get CHUNK_COUNT long 43 | get CHUNK_NEXT longlong 44 | 45 | set FILE_COUNT long 0 46 | 47 | for 48 | goto CHUNK_NEXT long 49 | 50 | get CHUNK_FILES long #can be 0 51 | get CHUNK_UNKNOWN long 52 | get CHUNK_START longlong 53 | get CHUNK_NEXT longlong 54 | get FILE_MIN long # 0/5000/etc 55 | get FILE_MAX long # 4999/9999/etc 56 | get NAME_OFFSET longlong 57 | get DATA_OFFSET longlong 58 | 59 | callfunction WRITE_CHUNK 1 60 | 61 | math FILE_COUNT += CHUNK_FILES 62 | 63 | if CHUNK_NEXT <= 0 #should be -1 64 | break 65 | endif 66 | 67 | #print "more chunks found" 68 | next 69 | 70 | if FILE_COUNT != TOTAL_FILES 71 | print "WARNING! wrong file_count=%FILE_COUNT% vs total_files=%TOTAL_FILES%" 72 | endif 73 | 74 | 75 | startfunction WRITE_CHUNK 76 | 77 | for i = 0 < CHUNK_FILES 78 | if VER >= 0x1b 79 | get OFFSET long 80 | get DUMMY2 long 81 | get NAME_HASH32 long 82 | get DUMMY4 long 83 | get SIZE long 84 | putarray 1 i OFFSET 85 | putarray 2 i NAME_HASH32 86 | putarray 3 i SIZE 87 | else 88 | get OFFSET long 89 | get ZERO long 90 | get NAME_HASH32 long 91 | get SIZE long 92 | putarray 1 i OFFSET 93 | putarray 2 i NAME_HASH32 94 | putarray 3 i SIZE 95 | endif 96 | next i 97 | 98 | goto NAME_OFFSET 99 | 100 | for i = 0 < CHUNK_FILES 101 | if VER >= 0x1d 102 | set NAME_HASH64 string "" 103 | get DUMMY28 long 104 | for j = 0 < 8 105 | get HASHBYTE byte 106 | string HASH2 p "%02x" HASHBYTE 107 | string NAME_HASH64 + HASH2 108 | next j 109 | get DUMMY30 long 110 | get DUMMY31 long 111 | get DUMMY32 long 112 | get DUMMY33 long 113 | get DUMMY34 long 114 | get DUMMY35 long 115 | get DUMMY36 long 116 | get DUMMY37 long 117 | get DUMMY38 long 118 | getdstring DUMMY39 0x110 119 | getarray OFFSET 1 i 120 | getarray NAME_HASH32 2 i 121 | getarray SIZE 3 i 122 | putarray 4 i NAME_HASH64 123 | if DUMMY28 == SIZE 124 | math ALT_SIZE == SIZE 125 | endif 126 | else 127 | get SIZE long 128 | get DUMMY29 long 129 | get DUMMY30-1 long 130 | get DUMMY30-2 long 131 | get DUMMY31 longlong 132 | get DUMMY32-1 long 133 | get DUMMY32-2 long 134 | get DUMMY33 long 135 | get DUMMY34 long 136 | get TYPE long 137 | getdstring NAME 0x80 138 | if VER >= 0x1b 139 | get DUMMY37 longlong 140 | get DUMMY38 longlong 141 | get DUMMY39 long 142 | else 143 | get DUMMY37 longlong 144 | get DUMMY38 longlong 145 | endif 146 | getarray OFFSET 1 i 147 | getarray NAME_HASH32 2 i 148 | getarray ALT_SIZE 3 i 149 | endif 150 | 151 | callfunction CHECK_FILEDATA 1 152 | next i 153 | endfunction 154 | 155 | startfunction CHECK_FILEDATA 156 | savepos TMP 157 | goto OFFSET 158 | if VER >= 0x1b && VER <= 0x1c 159 | get DUMMY3-01 long 160 | if DUMMY6 == 1 161 | math ACTUAL_OFFSET == OFFSET 162 | math ACTUAL_SIZE == SIZE 163 | else 164 | math ACTUAL_OFFSET == OFFSET 165 | math ACTUAL_OFFSET + 4 166 | xmath ACTUAL_SIZE "SIZE - 4" 167 | endif 168 | elif VER >= 0x1d 169 | math ACTUAL_OFFSET == OFFSET 170 | math ACTUAL_SIZE == SIZE 171 | else 172 | idstring "FILEDATA" 173 | getdstring FILEDATA_NAME 0x80 174 | getdstring ZERO 0xff 175 | get ACTUAL_CRC1 long 176 | get ACTUAL_SIZE long 177 | get ACTUAL_CRC2 longlong 178 | get DUMMY2-01 long 179 | get DUMMY2-02 long 180 | get DUMMY2-03 long 181 | get DUMMY2-04 long 182 | get DUMMY2-05 long 183 | get DUMMY2-06 long 184 | get ACTUAL_TYPE long 185 | get DUMMY2-08 long 186 | get DUMMY2-09 byte 187 | if ACTUAL_SIZE == 0 188 | math ACTUAL_SIZE == SIZE 189 | # todo: validate the "extraction" process when the SIZE value is ultimately 0 190 | endif 191 | savepos ACTUAL_OFFSET 192 | endif 193 | if VER >= 0x1d 194 | string FILEDATA_NAME p "0x%08x\0x%08x\0x%08x_0x%s" DUMMY37 DUMMY31 NAME_HASH32 NAME_HASH64 195 | else 196 | set FILEDATA_NAME string NAME 197 | if FILEDATA_NAME == "" 198 | if VER >= 0x1b 199 | string FILEDATA_NAME p "0x%08x\0x%08x" TYPE NAME_HASH32 200 | else 201 | string FILEDATA_NAME p "0x%08x\0x%08x" ACTUAL_TYPE ACTUAL_CRC1 202 | endif 203 | endif 204 | endif 205 | 206 | 207 | if ADD_COMPRESSED_EXTENSION != 0 208 | goto ACTUAL_OFFSET 209 | get COMPRESSED_ID long 210 | if COMPRESSED_ID == 0x57FBAA33 || COMPRESSED_ID == 0x1004FA99 || COMPRESSED_ID == 0x99FA0410 || COMPRESSED_ID == 0x57FBAA33 211 | string FILEDATA_NAME += ".compressed" 212 | endif 213 | endif 214 | 215 | log FILEDATA_NAME ACTUAL_OFFSET ACTUAL_SIZE 216 | 217 | goto TMP 218 | endfunction 219 | -------------------------------------------------------------------------------- /seiken_densetsu_4.bms: -------------------------------------------------------------------------------- 1 | # Seiken Densetsu 4/Dawn of Mana (PS2) 2 | # --- 3 | # for now, this script only covers the Japanese release of the game 4 | 5 | open FDSE "SLPM_665.76" 6 | open FDSE "data.bin" 1 7 | open FDSE "modules.bin" 2 8 | 9 | goto 0x553960 10 | xmath data_bin_files "0x86c8 >> 3" 11 | for i = 0 < data_bin_files 12 | get file_number long 13 | putarray 1 i file_number 14 | get file_offset long 15 | putarray 2 i file_offset 16 | next i 17 | xmath modules_bin_files "0x24 >> 2" 18 | for j = 0 < modules_bin_files 19 | get file_size long 20 | putarray 5 j file_size 21 | next j 22 | 23 | getarray file_name_index_offset 2 11 24 | math file_name_index_offset << 11 25 | goto file_name_index_offset 1 26 | for i = 0 < 0x11a3 27 | get additional_file_info line 1 28 | string additional_file_info R "," " " 29 | string file_name_info S additional_file_info file_name file_number 30 | putarray 3 i file_name 31 | putarray 4 i file_number 32 | next i 33 | 34 | xmath last_file "data_bin_files - 1" 35 | math j2 = 0 36 | for i = 0 < data_bin_files 37 | getarray file_number 1 i 38 | getarray file_offset 2 i 39 | set file_name string "" 40 | for j = j2 < 0x11a3 41 | getarray file_name_string 3 j 42 | getarray file_name_id 4 j 43 | if file_name_id != file_number 44 | math j + 1 45 | else 46 | string file_name p "data\%s" file_name_string 47 | break 48 | endif 49 | next j2 50 | if i != last_file 51 | math i + 1 52 | getarray file_size 2 i 53 | math i - 1 54 | math file_size - file_offset 55 | else 56 | math file_size = 0 57 | endif 58 | math file_offset << 11 59 | math file_size << 11 60 | if file_size != 0 61 | log file_name file_offset file_size 1 62 | endif 63 | next i 64 | 65 | math file_offset = 0 66 | putarray 6 0 "modules\sio2man.irx" 67 | putarray 6 1 "modules\padman.irx" 68 | putarray 6 2 "modules\mcman.irx" 69 | putarray 6 3 "modules\mcserv.irx" 70 | putarray 6 4 "modules\msifrpc.irx" 71 | putarray 6 5 "modules\libsd.irx" 72 | putarray 6 6 "modules\cdvdstm.irx" 73 | putarray 6 7 "modules\mcd.irx" 74 | putarray 6 8 "modules\sddrv_cd.irx" 75 | for j = 0 < modules_bin_files 76 | getarray file_size 5 j 77 | getarray file_name 6 j 78 | xmath temp_01 "(file_offset + file_size) - 1" 79 | goto temp_01 2 80 | math file_size_02 = file_size 81 | for blank_spaces = 0 82 | get blank_space byte 2 83 | goto -2 2 SEEK_CUR 84 | if blank_space == 0xcd 85 | math file_size_02 - 1 86 | else 87 | break 88 | endif 89 | next 90 | log file_name file_offset file_size_02 2 91 | math file_offset + file_size 92 | next j 93 | -------------------------------------------------------------------------------- /shaun_white_snowboarding_fat_lin.bms: -------------------------------------------------------------------------------- 1 | # Ubisoft - .fat+.lin 2 | # --- 3 | # Shaun White Snowboarding (PlayStation 2) - PS2_L.[FAT+LIN] 4 | # Shaun White Snowboarding (PlayStation Portable) - PSP_L.[FAT+LIN] 5 | # --- 6 | # apparently this kind of file format is part of an game engine internally named Opal, 7 | # sometimes referred to as "Opal Engine" in the game files. 8 | # although this one acts as a "generic file archival container" of sorts... 9 | 10 | math fat_num = 0 11 | math lin_num = 0 12 | get ext1 extension 13 | if ext1 == "FAT" 14 | math lin_num = 1 15 | callfunction load1 1 16 | elif ext1 == "LIN" 17 | math fat_num = 1 18 | callfunction load1 1 19 | endif 20 | 21 | startfunction load1 22 | open FDDE "FAT" fat_num 23 | open FDDE "LIN" lin_num 24 | get fat_size asize fat_num 25 | math fat_pos = 0 26 | do 27 | goto fat_pos fat_num 28 | get file_info line fat_num 29 | string file_elements S file_info file_name file_offset file_size 30 | log file_name file_offset file_size lin_num 31 | savepos fat_pos fat_num 32 | while fat_pos < fat_size 33 | endfunction 34 | -------------------------------------------------------------------------------- /shellshock_nam67.bms: -------------------------------------------------------------------------------- 1 | # Shellshock Nam' 67 (2004) - ASSETS.DAT 2 | 3 | get file filename 4 | if file != "ASSETS.DAT" 5 | cleanexit 6 | endif 7 | 8 | get dat_basename basename 9 | get dat_header_size long 10 | get dat_files long 11 | get dat_assets long 12 | get dat_04 long 13 | get dat_05 long 14 | get dat_06 long 15 | for i = 0 < dat_files 16 | get file_size long 17 | get file_offset long 18 | get file_name_offset long 19 | math file_name_offset + 0x18 20 | savepos dat_tmp1 21 | goto file_name_offset 22 | get file_name string 23 | goto dat_tmp1 24 | get dat_number long 25 | if dat_number == 0 26 | string archive_name p "%s.DAT" dat_basename 27 | else 28 | string archive_name p "%s%02d.DAT" dat_basename dat_number 29 | endif 30 | open FDSE archive_name 1 31 | log file_name file_offset file_size 1 32 | next i 33 | -------------------------------------------------------------------------------- /siren.bms: -------------------------------------------------------------------------------- 1 | # Siren/Forbidden Siren - taiken.tbl, siren.tbl, siren0.tbl 2 | 3 | get tbl_name basename 4 | get tbl_ext extension 5 | 6 | if tbl_ext != "tbl" 7 | cleanexit 8 | endif 9 | 10 | goto 0 11 | filexor 0xff 12 | idstring "SDT4" 13 | get files long 14 | get tbl_size long 15 | get tbl03 long # probably some kind of hash 16 | get file_info_index_offset long 17 | get file_name_index_offset long 18 | get tbl06 long 19 | goto file_info_index_offset 20 | math tbl_arcnum = 0 21 | math tbl_tempnum = 0 22 | math tbl_arcsize = 0x20000000 23 | for i = 0 < files 24 | get file_01 long 25 | get file_02 long 26 | get file_03 long 27 | xmath file_01_01 "file_01 & 0x7fffffff" 28 | xmath file_01_02 "(file_01 >> 31) & 1" 29 | putarray 0 i file_01_01 30 | putarray 1 i file_01_02 31 | putarray 2 i file_02 32 | math file_03 + file_name_index_offset 33 | putarray 3 i file_03 34 | next i 35 | 36 | for i = 0 < files 37 | getarray file_sector 0 i 38 | getarray dual_layer_flag 1 i 39 | getarray file_size 2 i 40 | getarray file_name_string_offset 3 i 41 | goto file_name_string_offset 0 42 | get file_name string 43 | if i == 0 44 | # literally *every* file is streamed through the disc itself. including the tbl. 45 | # because this script wasn't designed for fancy PS2 disc dump handling 46 | # through an executable in mind have to devise some workarounds... 47 | # (standard disc filesystem exposes the existence of a tbl file plus some numbered files) 48 | # on another note, as a limitation of the tbl format, the file sector value in which 49 | # the file is supposed to be streamed from must have a set number 50 | # regardless of whether or not said file is in a second DVD layer. 51 | math base_sector == file_sector 52 | endif 53 | math file_sector - base_sector 54 | xmath file_offset_within_split_part "(file_sector << 11) % tbl_arcsize" 55 | xmath tbl_arcnum "file_sector / (tbl_arcsize >> 11)" 56 | xmath parts_needed_for_file "((file_offset_within_split_part + file_size) / tbl_arcsize) + 1" 57 | xmath last_part "parts_needed_for_file - 1" 58 | math size_leftovers == file_size 59 | filexor "" 60 | for j = 0 < parts_needed_for_file 61 | if j == 0 62 | math targeted_arcnum == tbl_arcnum 63 | math arcnum_leftovers == parts_needed_for_file 64 | endif 65 | callfunction set_load_name 1 66 | set arcnum_load string load_name 67 | open fdse arcnum_load 1 68 | if j == 0 69 | if parts_needed_for_file == 1 70 | math chunk_size == file_size 71 | else 72 | xmath chunk_size "tbl_arcsize - file_offset_within_split_part" 73 | endif 74 | else 75 | math file_offset_within_split_part == 0 76 | xmath chunk_size "(file_offset_within_split_part + size_leftovers) % tbl_arcsize" 77 | endif 78 | append 79 | log file_name file_offset_within_split_part chunk_size 1 80 | append 81 | math targeted_arcnum + 1 82 | math arcnum_leftovers - 1 83 | math size_leftovers - chunk_size 84 | next j 85 | filexor 0xff 86 | next i 87 | 88 | startfunction set_load_name 89 | if tbl_name == "siren0" 90 | # crappy work-around for the Asian release of the first Siren game. 91 | # that one release in particular was in form of a DVD-9 (an dual-layer DVD) file 92 | # meaning that there were effectively *two* layers to choose from when it came 93 | # for the game to load whichever data had to be loaded from which layer through 94 | # the tbl file that was always streamed from the disc itself. 95 | # why it had to be this way was so there was all the essential engine data on one layer 96 | # and all the videos needed for the game to play (in standard pss format) on another layer. 97 | string load_name p "%s%01d.%03d" tbl_name dual_layer_flag targeted_arcnum 98 | else 99 | # other releases of the first game didn't have this unique method 100 | # of handling things as the Asian release. 101 | string load_name p "%s.%03d" tbl_name targeted_arcnum 102 | endif 103 | endfunction 104 | -------------------------------------------------------------------------------- /siren_2.bms: -------------------------------------------------------------------------------- 1 | # Siren 2/Forbidden Siren 2 - SPK.ROM/ROM.### 2 | 3 | open FDSE "SPK.ROM" 0 4 | 5 | idstring "SLPK" 6 | get slpk01 long 7 | get files long 8 | get name_pos long 9 | get slpk04 long 10 | get slpk05 long 11 | get slpk06 long 12 | get slpk07 long 13 | 14 | for i = 0 < files 15 | get file_name_off long 16 | math file_name_off + name_pos 17 | get archive_name_off long 18 | math archive_name_off + name_pos 19 | get file_offset long 20 | get file_size long 21 | 22 | savepos tmp1 23 | goto file_name_off 24 | get file_name string 25 | goto archive_name_off 26 | get archive_name string 27 | goto tmp1 28 | 29 | open FDSE archive_name 1 30 | log file_name file_offset file_size 1 31 | next i 32 | -------------------------------------------------------------------------------- /smash_court_pro_tournament.bms: -------------------------------------------------------------------------------- 1 | # Smash Court Pro Tournament/Smash Court Tennis Pro Tournament (PS2, Namco System 246) - DATA.[TBL/BIN] 2 | 3 | open FDDE "TBL" 0 4 | open FDDE "BIN" 1 5 | 6 | get tbl_files long 0 7 | get bin_files long 1 8 | 9 | if tbl_files = bin_files 10 | math files = tbl_files 11 | endif 12 | 13 | for i = 0 < files 14 | get file_info_location long 0 15 | savepos tbl_pos_01 0 16 | goto file_info_location 0 17 | get file_size long 0 18 | get file_02 long 0 19 | math sv = 0xff 20 | set file_name string "" 21 | for s = 0 22 | get string_char byte 0 23 | if string_char == 0 24 | break 25 | else 26 | xmath st "string_char ^ sv" 27 | string st = st 28 | string file_name + st 29 | if s == 9 30 | math sv + 26 31 | elif s == 19 32 | math sv + 26 33 | elif s == 28 34 | math sv + 26 35 | else 36 | math sv - 3 37 | endif 38 | endif 39 | next s 40 | goto tbl_pos_01 0 41 | get file_offset long 1 42 | log file_name file_offset file_size 1 43 | next i 44 | -------------------------------------------------------------------------------- /sound_fat_big.bms: -------------------------------------------------------------------------------- 1 | # Ubisoft - .fat+.big 2 | # --- 3 | # Prince of Persia: The Sands of Time 4 | # Prince of Persia: Revelations (PlayStation Portable) - SOUNDPSP.[FAT+BIG] 5 | 6 | math fat_num = 0 7 | math big_num = 0 8 | get ext1 extension 9 | if ext1 == "fat" 10 | math big_num = 1 11 | callfunction load1 1 12 | elif ext1 == "big" 13 | math fat_num = 1 14 | callfunction load1 1 15 | endif 16 | 17 | startfunction load1 18 | open FDDE "fat" fat_num 19 | open FDDE "big" big_num 20 | get fat_size asize fat_num 21 | for fat_pos = 0 < fat_size 22 | goto fat_pos fat_num 23 | get current_position long fat_num 24 | get file_offset long fat_num 25 | get file_size long fat_num 26 | get DUMMY4 long fat_num 27 | if DUMMY4 != 0 28 | print " non-zero reserved number is here " 29 | endif 30 | get file_name_string_size long fat_num 31 | math fat_pos + 20 32 | math fat_pos + file_name_string_size 33 | getdstring file_name file_name_string_size 34 | log file_name file_offset file_size big_num 35 | next 36 | endfunction 37 | -------------------------------------------------------------------------------- /sound_fat_bin.bms: -------------------------------------------------------------------------------- 1 | # Ubisoft - sound.fat + (sound.bin, stream.bin) 2 | # --- 3 | # Beowulf: The Game (Windows, PlayStation 3, Xbox 360) 4 | 5 | putarray 0 0 "" 6 | putarray 0 1 "English" 7 | putarray 0 2 "Japanese" 8 | putarray 0 3 "German" 9 | putarray 0 4 "French" 10 | putarray 0 5 "Spanish" 11 | putarray 0 6 "Italian" 12 | putarray 0 7 "Korean" 13 | putarray 0 8 "TChinese" 14 | putarray 0 9 "Portuguese" 15 | putarray 0 10 "SChinese" 16 | putarray 0 11 "Polish" 17 | putarray 0 12 "Russian" 18 | putarray 0 13 "Hungarian" 19 | putarray 0 14 "Czech" 20 | 21 | # these are all of the languages (see above) that were referenced in Beowulf exe 22 | 23 | get fat_name filename 24 | 25 | if fat_name != "sound.fat" 26 | cleanexit 27 | endif 28 | 29 | endian big 30 | get fat_sign long 31 | if fat_sign == 0x0000005a 32 | endian big 33 | elif fat_sign == 0x0000bc42 34 | endian little 35 | else 36 | cleanexit 37 | endif 38 | get languages long 39 | for i = 0 < languages 40 | get lang_num long 0 41 | putarray 1 i lang_num 42 | next i 43 | get bao_entries long 44 | string sound_bin_name p "sound.bin" 45 | open FDSE sound_bin_name 1 46 | math bao_name_type = 0 47 | math multilingual = 0 48 | for i1 = 0 < bao_entries 49 | get level_id long 50 | get sub_entries long 51 | for j1 = 0 < sub_entries 52 | math bao_name_type = 1 53 | callfunction get_bao_info 1 54 | next j1 55 | next i1 56 | math multilingual = 1 57 | for i2 = 0 < languages 58 | getarray lang_num 1 i2 59 | getarray lang_name 0 lang_num 60 | for j2 = 0 < bao_entries 61 | get sub_entries long 62 | for j3 = 0 < sub_entries 63 | math language_sub_entry = j2 64 | math language_sub_entry + 1 65 | math bao_name_type = 2 66 | callfunction get_bao_info 1 67 | next j3 68 | next j2 69 | next i2 70 | 71 | startfunction get_bao_info 72 | get bao_id long 73 | get bao_offset long 74 | get bao_size long 75 | if bao_name_type = 1 76 | #string bao_name p "%08x/%08x.bao" level_id bao_id 77 | string bao_name p "%08x.bao" bao_id 78 | elif bao_name_type = 2 79 | #string bao_name p "%s/%04d/%08x.bao" lang_name language_sub_entry bao_id 80 | string bao_name p "%s/%08x.bao" lang_name bao_id 81 | else 82 | set bao_name string "00000000.bao" 83 | endif 84 | xmath is_stream "bao_id & 0xf0000000" 85 | if is_stream == 0x50000000 86 | math sb_exists = 0 87 | if multilingual = 0 88 | string stream_bin_name p "stream.bin" 89 | elif multilingual = 1 90 | string stream_bin_name p "%s/stream.bin" lang_name 91 | endif 92 | open FDSE stream_bin_name 2 EXISTS 93 | if EXISTS == 1 94 | math sb_exists = 1 95 | endif 96 | if sb_exists = 1 97 | log bao_name bao_offset bao_size 2 98 | endif 99 | else 100 | log bao_name bao_offset bao_size 1 101 | endif 102 | endfunction 103 | -------------------------------------------------------------------------------- /stuntman_xav.bms: -------------------------------------------------------------------------------- 1 | idstring "XAVS" 2 | get video_height short 3 | get video_width short 4 | get xav_03 long 5 | get xav_audio_layers short 6 | get xav_05 short 7 | get xav_06 long 8 | get xav_07 long 9 | savepos xav_offset 10 | goto xav_offset 11 | get xav_size asize 12 | get xav_name basename 13 | append 14 | do 15 | get chunk_info long 16 | savepos chunk_offset 17 | xmath chunk_size "(chunk_info & 0x00ffff00) >> 8" 18 | xmath chunk_type "chunk_info & 0x000000ff" 19 | if chunk_info == 0x30562421 20 | elif chunk_info == 0x31562421 21 | elif chunk_info == 0x534f455f 22 | else 23 | if chunk_type == 0x56 24 | /* 25 | # iqval 26 | 08 10 10 13 10 13 16 16 16 16 16 16 1A 18 1A 1B 27 | 1B 1B 1A 1A 1A 1A 1B 1B 1B 1D 1D 1D 22 22 22 1D 28 | 1D 1D 1B 1B 1D 1D 20 20 22 22 25 26 25 23 23 22 29 | 23 26 26 28 28 28 30 30 2E 2E 38 38 3A 45 45 53 30 | 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 31 | 32 | # vqval 33 | 00 00 21 04 42 08 E0 03 84 10 A5 14 C6 18 E7 1C 34 | 1F 00 29 25 4A 29 00 7C 8C 31 AD 35 FF 7F CE 39 35 | */ 36 | endif 37 | string temp_name p "%s.%02x" xav_name chunk_type 38 | log temp_name chunk_offset chunk_size 39 | math chunk_offset + chunk_size 40 | endif 41 | goto chunk_offset 42 | while chunk_offset < xav_size 43 | append 44 | -------------------------------------------------------------------------------- /sylpheed_ipfb.bms: -------------------------------------------------------------------------------- 1 | # PROJECT SYLPHEED (Xbox 360) - *.pak+.p## 2 | 3 | get ext extension 4 | if ext == "pak" 5 | get pak_name basename 6 | endian big 7 | get is_ipfb long 8 | if is_ipfb != 0x49504642 # IPFB 9 | cleanexit 10 | endif 11 | get files long 12 | get block_size long 13 | get max_p_size long 14 | for i = 0 < files 15 | get hardcoded_name_hash long 16 | putarray 0 i hardcoded_name_hash 17 | get file_offset long 18 | putarray 1 i file_offset 19 | get file_size long 20 | putarray 2 i file_size 21 | next i 22 | for i = 0 < files 23 | getarray hardcoded_name_hash 0 i 24 | getarray file_offset 1 i 25 | getarray file_size 2 i 26 | math target == file_offset 27 | callfunction fetch_p_file 1 28 | xmath local_file_offset "file_offset % max_p_size" 29 | putarray 3 i local_file_offset 30 | string temp_name p "%u." hardcoded_name_hash 31 | log temp_name local_file_offset file_size 1 32 | next i 33 | else 34 | cleanexit 35 | endif 36 | 37 | startfunction fetch_p_file 38 | xmath p_num "target / max_p_size" 39 | string p_file p "p%02d" p_num 40 | open FDDE p_file 1 41 | endfunction 42 | -------------------------------------------------------------------------------- /tekken_tag_tournament.bms: -------------------------------------------------------------------------------- 1 | # Tekken Tag Tournament (PS2) 2 | 3 | math ttt_ver = 0 4 | 5 | get elf_name filename 6 | if elf_name == "SLPS_200.15" 7 | # Japan (2000/03/30) 8 | callfunction read_elf 1 9 | elif elf_name == "SLUS_200.01" 10 | # USA (2000/10/26) 11 | callfunction read_elf 1 12 | elif elf_name == "SCES_500.01" 13 | # Europe (2000/11/24) 14 | callfunction read_elf 1 15 | elif elf_name == "SCED_500.41" 16 | # United Kingdom/Great Britain/England - Official PlayStation 2 Magazine Issue 2 (2000/12/04) 17 | callfunction read_elf 1 18 | elif elf_name == "SCPS_560.02" 19 | # South Korea (2002/02/22) 20 | callfunction read_elf 1 21 | else 22 | print " wrong file(no, tekken.bin does not count). " 23 | cleanexit 24 | endif 25 | 26 | open FDSE elf_name 0 27 | open FDSE "tekken.bin" 1 28 | 29 | if ttt_ver = 1 30 | xmath ttt_info_entries "(ttt_info_offset_02 - ttt_info_offset_01) / 0xc" 31 | elif ttt_ver = 2 32 | xmath ttt_info_entries "(ttt_info_offset_02 - ttt_info_offset_01) / 0x10" 33 | endif 34 | 35 | goto ttt_info_offset_01 36 | for i = 0 < ttt_info_entries 37 | if ttt_ver = 1 38 | get file_offset long 39 | get file_size long 40 | get ttt_03 long 41 | elif ttt_ver = 2 42 | get file_offset long 43 | get file_size long 44 | get ttt_03 long 45 | get file_id long 46 | endif 47 | 48 | if i = 0 49 | math iso9660_base_offset = file_offset 50 | endif 51 | 52 | math file_offset - iso9660_base_offset 53 | math file_offset << 11 54 | 55 | if file_size == 0x3509 56 | elif file_size == 0x350a 57 | else 58 | math file_size - 0x350a 59 | log "" file_offset file_size 1 60 | endif 61 | next i 62 | 63 | startfunction read_elf 64 | idstring "\x7fELF" 65 | get elf_01 byte 66 | get elf_02 byte 67 | get elf_03 short 68 | getdstring elf_04 8 69 | get e_type short 70 | get e_machine short 71 | get e_version long 72 | get e_entry long 73 | get e_phoff long 74 | get e_shoff long 75 | get e_flags long 76 | get e_ehsize short 77 | get e_phentsize short 78 | get e_phnum short 79 | get e_shentsize short 80 | get e_shnum short 81 | get e_shstrndx short 82 | 83 | goto e_phoff 84 | if e_phnum == 5 # work-around for SCPS_560.02(korean exe of the game) 85 | getdstring p_dummy 8 86 | endif 87 | for ph = 0 < e_phnum 88 | get p_type long 89 | get p_offset long 90 | get p_vaddr long 91 | get p_filesz long 92 | get p_memsz long 93 | get p_flags long 94 | get p_align long 95 | next ph 96 | 97 | savepos elf_pos01 98 | 99 | goto e_shoff 100 | for sh = 0 < e_shnum 101 | get sh_name long 102 | get sh_type long 103 | get sh_flags long 104 | get sh_addr long 105 | get sh_offset long 106 | get sh_size long 107 | get sh_link long 108 | get sh_info long 109 | get sh_addralign long 110 | get sh_entsize long 111 | next sh 112 | 113 | goto elf_pos01 114 | get elf_05 long 115 | get elf_06 long 116 | get elf_07 long 117 | 118 | if elf_05 == 0x01b8b730 # Japan (1.30) 119 | math ttt_ver = 1 120 | math ttt_info_offset_01 = 0x1b9000 121 | math ttt_info_offset_02 = 0x1bb310 122 | elif elf_05 == 0x01b8bc30 # Japan (2.00) 123 | math ttt_ver = 1 124 | math ttt_info_offset_01 = 0x1b94b0 125 | math ttt_info_offset_02 = 0x1bb7c0 126 | elif elf_05 == 0x01bac8e8 # South Korea (1.01) 127 | math ttt_ver = 2 128 | math ttt_info_offset_01 = 0x1c7640 129 | math ttt_info_offset_02 = 0x1ca500 130 | elif elf_05 == 0x01bb1bb0 # Japan (3.00) 131 | math ttt_ver = 2 132 | math ttt_info_offset_01 = 0x1baf10 133 | math ttt_info_offset_02 = 0x1bddd0 134 | elif elf_05 == 0x01c8daf0 # Official PlayStation 2 Magazine Issue 2 (1.00) 135 | math ttt_ver = 2 136 | math ttt_info_offset_01 = 0x1caf60 137 | math ttt_info_offset_02 = 0x1cde20 138 | elif elf_05 == 0x01c8ddf0 # USA (1.00) 139 | math ttt_ver = 2 140 | math ttt_info_offset_01 = 0x1cad40 141 | math ttt_info_offset_02 = 0x1cdc00 142 | elif elf_05 == 0x01c8def0 # USA (2.00) 143 | math ttt_ver = 2 144 | math ttt_info_offset_01 = 0x1cae40 145 | math ttt_info_offset_02 = 0x1cdd00 146 | elif elf_05 == 0x01c91df0 # Europe (1.00, 2.00) 147 | math ttt_ver = 2 148 | math ttt_info_offset_01 = 0x1cf1c0 149 | math ttt_info_offset_02 = 0x1d2080 150 | endif 151 | endfunction 152 | -------------------------------------------------------------------------------- /tekken_tag_tournament_2.bms: -------------------------------------------------------------------------------- 1 | # Tekken Tag Tournament 2 (System 369, PS3, Xbox 360, Wii U) 2 | # --- 3 | # from what i've seen, the PS3 and Wii U versions of the game uses some sort of encryption method for its data###.bin files, 4 | # as for the Xbox 360 version said files are compressed into raw lzx/xmemlzx/xmemdecompress files. 5 | # and this is for data###.bin files that doesn't store either audio(nus3bank) or video(pam/wmv/usm), these are the ones that are exempt from either method. 6 | # this script will extract every single file that exists there through either nrfo.bin or data###.ofs as-is, 7 | # so the only useful thing you'll get out of them are .nus3bank and .pam/.wmv/.usm files, respectively. 8 | 9 | get ttt2_file basename 10 | get ttt2_ext extension 11 | math file_number = 0 12 | 13 | if ttt2_ext == "bin" 14 | endian big 15 | if ttt2_file == "nrfo" 16 | get ofs_files long 17 | math data_part = 0 18 | math mode = 1 19 | for i = 0 < ofs_files 20 | string data_name p "data%03d" data_part 21 | string bin_name p "%s.bin" data_name 22 | string ofs_name p "%s.ofs" data_name 23 | open FDSE bin_name 1 EXISTS 24 | if EXISTS = 0 25 | math data_part + 1 26 | math i - 1 27 | else 28 | get ofs_offset long 29 | get ofs_size long 30 | if mode = 0 31 | log ofs_name ofs_offset ofs_size 32 | elif mode = 1 33 | callfunction parse_ofs 1 34 | endif 35 | math data_part + 1 36 | endif 37 | next i 38 | endif 39 | elif ttt2_ext == "ofs" 40 | endian big 41 | callfunction parse_ofs 1 42 | elif ttt2_ext == "dat" 43 | # (todo) figure out index.dat 44 | endian little 45 | get sarc_sign long 46 | if sarc_sign != 0x63726173 47 | break 48 | endif 49 | get sarc_files long 50 | for i = 0 < sarc_files 51 | get file_size longlong 52 | get file_offset longlong 53 | log "" file_offset file_size 54 | next i 55 | endif 56 | 57 | startfunction parse_ofs 58 | math bin_pos = 0 59 | math ofs_pos = 0 60 | if ttt2_ext == "bin" 61 | if ttt2_file == "nrfo" 62 | log MEMORY_FILE ofs_offset ofs_size 63 | endif 64 | elif ttt2_ext == "ofs" 65 | open FDDE "bin" 1 66 | get ofs_size asize 0 67 | endif 68 | get bin_size asize 1 69 | math file_number = 1 70 | for bin_pos = bin_pos < bin_size 71 | goto bin_pos file_number 72 | callfunction isobmff 1 73 | math bin_pos + chunk_size 74 | next 75 | if ttt2_ext == "bin" 76 | if ttt2_file == "nrfo" 77 | math file_number = -1 78 | endif 79 | elif ttt2_ext == "ofs" 80 | math file_number = 0 81 | endif 82 | for ofs_pos = ofs_pos < ofs_size 83 | goto ofs_pos file_number 84 | callfunction isobmff 1 85 | math ofs_pos + chunk_size 86 | next 87 | math files = ofsi_files 88 | for file = 0 < files 89 | getarray file_hash 1 file 90 | getarray file_02 2 file 91 | getarray file_offset 3 file 92 | getarray remaining_file_size 4 file 93 | math file + 1 94 | getarray next_file_offset 3 file 95 | math file - 1 96 | xmath actual_file_offset "file_offset + imge_offset" 97 | if remaining_file_size = 0 98 | xmath actual_file_size "next_file_offset - file_offset" 99 | else 100 | xmath actual_file_size "((next_file_offset - file_offset) - (1 << 4)) | remaining_file_size" 101 | endif 102 | if ttt2_ext == "bin" 103 | if ttt2_file == "nrfo" 104 | string file_name p "%s/%08x." data_name file_hash 105 | endif 106 | elif ttt2_ext == "ofs" 107 | string file_name p "%08x." file_hash 108 | endif 109 | log file_name actual_file_offset actual_file_size 1 110 | next file 111 | endfunction 112 | 113 | startfunction isobmff 114 | get chunk_size long file_number 115 | get chunk_type long file_number 116 | if chunk_type == 0x66747970 117 | get file_type_01 long file_number 118 | get file_sign long file_number 119 | get file_type_02 long file_number 120 | if file_type_01 == file_type_02 121 | math file_type == file_type_02 122 | endif 123 | endif 124 | if chunk_type == 0x68656164 125 | if file_type == 0x6e72666f 126 | get bin_type long file_number 127 | endif 128 | endif 129 | if chunk_type == 0x696d6765 130 | savepos imge_offset file_number 131 | endif 132 | if chunk_type == 0x6f667369 133 | xmath ofsi_files "(chunk_size - 8) >> 3" 134 | for ofsi_count = 0 < ofsi_files 135 | get file_hash long file_number 136 | putarray 1 ofsi_count file_hash 137 | get file_02 long file_number 138 | putarray 2 ofsi_count file_02 139 | next ofsi_count 140 | endif 141 | if chunk_type == 0x6f667364 142 | xmath ofso_files "(chunk_size - 8) >> 2" 143 | for ofso_count = 0 < ofso_files 144 | get file_03 long file_number 145 | xmath file_offset "file_03 & 0xfffffff0" 146 | putarray 3 ofso_count file_offset 147 | xmath remaining_file_size "file_03 & 0xf" 148 | putarray 4 ofso_count remaining_file_size 149 | next ofso_count 150 | endif 151 | endfunction 152 | -------------------------------------------------------------------------------- /the_bouncer.bms: -------------------------------------------------------------------------------- 1 | # The Bouncer 2 | # --- 3 | # v1 by AnonBaiter (initial version) 4 | # v2 by bnnm (.nam names) 5 | # v3 by AnonBaiter (filling in the gaps) 6 | # v4 by AnonBaiter (removing "sz" part as there's no need for that) 7 | # v5 by AnonBaiter (massive re-write around here) 8 | 9 | get bouncer_filename filename 10 | get bouncer_extension extension 11 | 12 | math 32bit_minus_one = 0xffffffff 13 | 14 | if bouncer_filename == "BOUNCER.bin" 15 | callfunction PARSE_BIN_1 1 16 | elif bouncer_filename == "bgmdata.bin" || bouncer_filename == "bgmlist.bin" || bouncer_filename == "bgmofst.bin" 17 | callfunction PARSE_BIN_2 1 18 | elif bouncer_filename == "bgmwddat.bin" || bouncer_filename == "bgmwdtbl.bin" 19 | callfunction PARSE_BIN_2 1 20 | elif bouncer_filename == "sdwddat.bin" || bouncer_filename == "sdwdtbl.bin" 21 | callfunction PARSE_BIN_3 1 22 | else 23 | if bouncer_extension == "tbl" || bouncer_extension == "nam" || bouncer_extension == "dat" 24 | open FDDE "tbl" 0 25 | open FDDE "nam" 1 26 | open FDDE "dat" 2 27 | math file_number = 0 28 | callfunction tbl_nam_bgmlist_init_header_info 1 29 | math file_number = 1 30 | callfunction tbl_nam_bgmlist_init_header_info 1 31 | math final_files = 0 32 | for i = 0 < tnb_files 33 | getarray file_offset 0 i 34 | getarray file_size 1 i 35 | getarray file_name 2 i 36 | if file_offset != 32bit_minus_one || file_size != 32bit_minus_one 37 | putarray 3 final_files file_offset 38 | putarray 4 final_files file_size 39 | putarray 5 final_files file_name 40 | math final_files + 1 41 | endif 42 | next i 43 | for i = 0 < final_files 44 | getarray file_offset 3 i 45 | math file_offset << 11 46 | getarray file_size 4 i 47 | getarray file_name 5 i 48 | log file_name file_offset file_size 2 49 | next i 50 | elif bouncer_extension == "bin" 51 | get is_iz01 long 52 | if is_iz01 == 0x31305a49 # IZ01 53 | get iz01_02 long 54 | if iz01_02 != 0 55 | cleanexit 56 | endif 57 | get iz01_03 long 58 | if iz01_03 != 0x72657375 59 | cleanexit 60 | endif 61 | get iz01_04 long 62 | if iz01_04 != 0 63 | cleanexit 64 | endif 65 | get iz01_05 long 66 | if iz01_05 != 1 67 | cleanexit 68 | endif 69 | get original_size long 70 | else 71 | goto 0 72 | callfunction PARSE_BIN_1 1 73 | endif 74 | endif 75 | endif 76 | 77 | startfunction PARSE_BIN_1 78 | get bin_files long 79 | xmath bin_file_info_sector_size "((bin_files + 1) * 4) + 8" 80 | xmath modulus_test_01 "bin_file_info_sector_size % (1 << 5)" 81 | if modulus_test != 0 82 | xmath iz01_size_collection_offset "((bin_file_info_sector_size >> 5) + 1) << 5" 83 | endif 84 | get name_string_collection_offset long 85 | math name_string_collection_offset << 11 86 | for i = 0 <= bin_files 87 | get file_offset long 88 | putarray 0 i file_offset 89 | next i 90 | if bouncer_filename == "BOUNCER.bin" 91 | math iz01_file_start = 7 92 | math last_uncompressed_file = 6 93 | goto iz01_size_collection_offset 94 | for i = 0 < bin_files 95 | if i <= last_uncompressed_file 96 | putarray 1 i 0 97 | elif i >= iz01_file_start 98 | get iz01_size long 99 | putarray 1 i iz01_size 100 | endif 101 | next i 102 | endif 103 | goto name_string_collection_offset 104 | for i = 0 < bin_files 105 | get file_name_string_offset long 106 | putarray 2 i file_name_string_offset 107 | next i 108 | xmath iso9660_block_size "1 << 11" 109 | for i = 0 < bin_files 110 | getarray file_name_string_offset 2 i 111 | math file_name_string_offset + iso9660_block_size 112 | goto file_name_string_offset 113 | get file_name string 114 | putarray 3 i file_name 115 | next i 116 | for i = 0 < bin_files 117 | getarray aid_01 0 i 118 | math i + 1 119 | getarray aid_02 0 i 120 | math i - 1 121 | xmath file_size "(aid_02 - aid_01) << 11" 122 | putarray 4 i file_size 123 | next i 124 | for i = 0 < bin_files 125 | getarray file_offset 0 i 126 | math file_offset << 11 127 | if bouncer_filename == "BOUNCER.bin" 128 | getarray iz01_decompressed_size 1 i 129 | endif 130 | getarray file_name 3 i 131 | getarray file_size 4 i 132 | log file_name file_offset file_size 133 | next i 134 | endfunction 135 | 136 | startfunction PARSE_BIN_2 137 | open FDSE "bgmlist.bin" 0 138 | open FDSE "bgmofst.bin" 1 139 | open FDSE "bgmdata.bin" 2 140 | open FDSE "bgmwdtbl.bin" 3 141 | open FDSE "bgmwddat.bin" 4 142 | math file_number = 0 143 | callfunction tbl_nam_bgmlist_init_header_info 1 144 | math file_number = 1 145 | math data_number = 2 146 | callfunction parse_tbl_dat_bin_headers 1 147 | math file_number = 3 148 | math data_number = 4 149 | callfunction parse_tbl_dat_bin_headers 1 150 | endfunction 151 | 152 | startfunction PARSE_BIN_3 153 | open FDSE "sdwdtbl.bin" 0 154 | open FDSE "sdwddat.bin" 1 155 | math file_number = 0 156 | math data_number = 1 157 | callfunction parse_tbl_dat_bin_headers 1 158 | endfunction 159 | 160 | startfunction parse_tbl_dat_bin_headers 161 | get id_01 long file_number 162 | get id_02 long file_number 163 | get td_files long file_number 164 | get td_block_size long file_number 165 | math a = 0 166 | for i = 0 < td_files 167 | get file_offset long file_number 168 | get file_size long file_number 169 | if file_offset != 32bit_minus_one || file_size != 32bit_minus_one 170 | putarray 11 a file_offset 171 | putarray 12 a file_size 172 | if id_01 == 0x4f4d4742 173 | if id_02 == 0x545346 174 | # "BGMOFST" 175 | getarray file_name 0 a 176 | endif 177 | endif 178 | if id_01 == 0x4d4742 179 | if id_02 == 0 180 | # "BGM" 181 | getarray file_name 1 a 182 | endif 183 | endif 184 | if id_01 == 0x4553 185 | if id_02 == 0 186 | # "SE" 187 | string file_name p "se%03d.wd" i 188 | endif 189 | endif 190 | putarray 13 a file_name 191 | math a + 1 192 | endif 193 | next i 194 | for i2 = 0 < a 195 | getarray file_offset 11 i2 196 | math file_offset << 11 197 | getarray file_size 12 i2 198 | getarray file_name 13 i2 199 | log file_name file_offset file_size data_number 200 | next i2 201 | endfunction 202 | 203 | startfunction tbl_nam_bgmlist_init_header_info 204 | math array_listing_is_generated = 0 205 | get tnb_01 long file_number 206 | get tnb_02 long file_number 207 | get tnb_files long file_number 208 | get tnb_04 long file_number 209 | if tnb_01 == 0 210 | get bgmlist_size asize file_number 211 | xmath bgmlist_files "((bgmlist_size - (1 << 4)) >> 4) >> 1" 212 | for i = 0 < bgmlist_files 213 | for j = 0 < 2 214 | get bgm_id long 0 215 | getdstring bgm_name 12 0 216 | if j = 0 217 | string bgm_name + ".bgm" 218 | elif j = 1 219 | string bgm_name + ".wd" 220 | endif 221 | putarray j bgm_id bgm_name 222 | next j 223 | next i 224 | endif 225 | if tnb_01 == 0x5453464f 226 | for i = 0 < tnb_files 227 | get file_offset long file_number 228 | get file_size long file_number 229 | if file_number = 0 230 | putarray 0 i file_offset 231 | putarray 1 i file_size 232 | endif 233 | next i 234 | endif 235 | if tnb_01 == 0x454d414e 236 | for i = 0 < tnb_files 237 | if file_number = 1 238 | getarray file_offset 0 i 239 | getarray file_size 1 i 240 | if file_offset != 32bit_minus_one || file_size != 32bit_minus_one 241 | getdstring file_name 8 file_number 242 | putarray 2 i file_name 243 | else 244 | putarray 2 i "" 245 | endif 246 | endif 247 | next i 248 | endif 249 | endfunction 250 | -------------------------------------------------------------------------------- /this_is_football.bms: -------------------------------------------------------------------------------- 1 | # FOOTBALL.CFS archive (This is Football, This is Football 2) 2 | 3 | idstring "CFS\x20" 4 | getdstring VER 4 5 | getdstring CREDIT 4 6 | getdstring YEAR 4 7 | getdstring DUMMY 16 8 | get HEADER_SIZE long 9 | get FILES long 10 | get NAME_OFF long 11 | savepos INFO_OFF 12 | 13 | goto NAME_OFF 14 | for i = 0 < FILES 15 | get NAME string 16 | putarray 0 i NAME 17 | next i 18 | 19 | goto INFO_OFF 20 | for i = 0 < FILES 21 | getarray NAME 0 i 22 | get XSIZE long 23 | get SIZE long 24 | get OFFSET long 25 | get DUMMY7 time 26 | get DUMMY8 long 27 | print "compressed size: %SIZE|x%" 28 | print "uncompessed size: %XSIZE|x%" 29 | if XSIZE == SIZE 30 | string TMPNAME1 p "[untouched]\%s" NAME 31 | log TMPNAME1 OFFSET SIZE 32 | else 33 | string TMPNAME2 p "[compressed]\%s" NAME 34 | log TMPNAME2 OFFSET SIZE 35 | endif 36 | next i 37 | -------------------------------------------------------------------------------- /this_is_football_2002.bms: -------------------------------------------------------------------------------- 1 | # SCEE London Studio/Team Soho/SCEE - *.PAK files 2 | 3 | getdstring pak_archive_sign 8 4 | if pak_archive_sign == "SceeWhPC" 5 | if pak_archive_sign == "SceeWhPk" 6 | else 7 | print " this script have never seen this kind of .PAK file before " 8 | cleanexit 9 | endif 10 | getdstring pak_timestamp 20 11 | get archive_info_size long 12 | get total_files long 13 | getdstring random_garbage 0x80 14 | for t1 = 0 < 28 15 | get file_name_offsets long 16 | next t1 17 | for t2 = 1 < 0x20 18 | getdstring file_extension 4 19 | putarray 1 t2 file_extension 20 | next t2 21 | 22 | goto 0x190 23 | get directory_overall_entries long 24 | get directory_overall_info_size long 25 | if directory_overall_entries != 0 && directory_overall_info_size != 0 26 | math current_i = 0 27 | savepos directory_info_offset 28 | xmath directory_entry_info_size "directory_overall_entries * 0x74" 29 | xmath directory_overall_base_offset "directory_info_offset + directory_entry_info_size" 30 | for directory = 0 < directory_overall_entries 31 | math singular_directory_entries = 0 32 | getdstring directory_extension 4 33 | getdstring directory_name 0x60 34 | get directory_entries_01 long 35 | get directory_entries_02 long 36 | get directory_entries_03 long 37 | get directory_offset long 38 | savepos directory_temp_position_01 39 | math directory_offset + directory_overall_base_offset 40 | goto directory_offset 41 | if directory_entries_02 == 0 || directory_entries_02 == 1 42 | if directory_entries_01 > directory_entries_03 43 | math singular_directory_entries == directory_entries_01 44 | elif directory_entries_01 < directory_entries_03 45 | math singular_directory_entries == directory_entries_03 46 | elif directory_entries_01 == directory_entries_03 47 | math singular_directory_entries == directory_entries_03 48 | endif 49 | else 50 | xmath singular_directory_entries "(directory_entries_03 - directory_entries_02) + 1" 51 | endif 52 | for i = 0 < singular_directory_entries 53 | get file_size long 54 | get file_offset long 55 | if pak_archive_sign == "SceeWhPC" 56 | get file_name_hash long 57 | endif 58 | if file_size != 0 59 | math file_offset << 11 60 | string file_name p "%s\%s.%s" directory_name i directory_extension 61 | if file_size & 0xc0000000 # 0x40000000 and 0x80000000 62 | savepos directory_temp_position_02 63 | goto file_offset 64 | get original_file_size long 65 | goto directory_temp_position_02 66 | math file_size & 0x3fffffff 67 | string TMP_NAME2 p "%s[compressed_0x%08x]" file_name original_file_size 68 | log TMP_NAME2 file_offset file_size 69 | else 70 | log file_name file_offset file_size 71 | endif 72 | math current_i + 1 73 | endif 74 | next i 75 | goto directory_temp_position_01 76 | next directory 77 | xmath goto_info_offset "directory_overall_base_offset + directory_overall_info_size" 78 | else 79 | math goto_info_offset == 0x198 80 | endif 81 | 82 | goto goto_info_offset 83 | set previous_file_name string "" 84 | 85 | for i = current_i < total_files 86 | get file_offset threebyte 87 | get name_recycling_number byte 88 | get name_size byte 89 | get file_id short 90 | get file_size long 91 | if pak_archive_sign == "SceeWhPC" 92 | get file_name_hash long 93 | endif 94 | math file_offset << 11 95 | set individual_file_name string "" 96 | xmath last_name_byte "name_size - 1" 97 | for n = 0 < name_size 98 | get string_char byte 99 | if n = last_name_byte 100 | math extension_number = string_char 101 | endif 102 | string string_char = string_char 103 | string individual_file_name + string_char 104 | next n 105 | if name_recycling_number == 0 106 | set previous_file_name string individual_file_name 107 | strlen previous_name_size previous_file_name 108 | set file_name string individual_file_name 109 | endif 110 | if name_recycling_number != 0 111 | set incomplete_file_name string "" 112 | for n2 = 0 < name_recycling_number 113 | getvarchr string_char previous_file_name n2 byte 114 | string string_char = string_char 115 | string incomplete_file_name + string_char 116 | next n2 117 | string incomplete_file_name + individual_file_name 118 | set file_name string incomplete_file_name 119 | set previous_file_name string incomplete_file_name 120 | endif 121 | if extension_number <= 0x1f 122 | getarray file_extension 1 extension_number 123 | string file_name - 1 124 | string file_name + "." 125 | string file_name + file_extension 126 | endif 127 | log file_name file_offset file_size 128 | next i 129 | -------------------------------------------------------------------------------- /tri-ace_ps2.bms: -------------------------------------------------------------------------------- 1 | goto 0x8000 2 | get type byte 3 | getdstring id 5 4 | get version byte 5 | get unused1 byte 6 | getdstring system_id 32 7 | getdstring volume_id 32 8 | getdstring unused2 8 9 | get volume_space_size_01 long 10 | get volume_space_size_02 long 11 | getdstring unused3 32 12 | get volume_set_size_01 short 13 | get volume_set_size_02 short 14 | get volume_sequence_number_01 short 15 | get volume_sequence_number_02 short 16 | get logical_block_size_01 short 17 | get logical_block_size_02 short 18 | get path_table_size_01 long 19 | get path_table_size_02 long 20 | get type_l_path_table long 21 | get opt_type_l_path_table long 22 | get type_m_path_table long 23 | get opt_type_m_path_table long 24 | getdstring root_directory_record 34 25 | getdstring volume_set_id 128 26 | getdstring publisher_id 128 27 | getdstring preparer_id 128 28 | getdstring application_id 128 29 | getdstring copyright_file_id 37 30 | getdstring abstract_file_id 37 31 | getdstring bibliographic_file_id 37 32 | getdstring creation_date 17 33 | getdstring modification_date 17 34 | getdstring expiration_date 17 35 | getdstring effective_date 17 36 | get file_structure_version byte 37 | get unused4 byte 38 | getdstring application_data 512 39 | getdstring unused5 653 40 | 41 | if volume_id == "STAROCEANTET " 42 | set bin_filename string "sotet.bin" 43 | set path_name string "STAROCEANTET" 44 | math bin_offset = 0x400 45 | math tri_ace = 1 46 | endif 47 | 48 | if volume_id == "RADIATA " 49 | set bin_filename string "radiata.bin" 50 | set path_name string "RADIATA" 51 | math bin_offset = 0x78d83 52 | math tri_ace = 1 53 | endif 54 | 55 | if volume_id == "VALKYRIEPROFILE2 " 56 | set bin_filename string "vp2.bin" 57 | set path_name string "VALKYRIEPROFILE2" 58 | math bin_offset = 0x400 59 | math tri_ace = 1 60 | endif 61 | 62 | if tri_ace = 1 63 | math bin_offset << 11 64 | goto bin_offset 65 | if bin_filename == "sotet.bin" 66 | math full_header_size = 0xf000 67 | math index_count = 0x1400 68 | math pos_01 = 0 69 | math memory_pos_01 = pos_01 70 | math pos_02 = 0x5000 71 | math memory_pos_02 = pos_02 72 | math pos_03 = 0xa000 73 | math memory_pos_03 = pos_03 74 | math num_01 = 0x13578642 75 | math num_02 = num_01 76 | elif bin_filename == "radiata.bin" 77 | math full_header_size = 0xd800 78 | math index_count = 0x1200 79 | math pos_01 = 0 80 | math memory_pos_01 = pos_01 81 | math pos_02 = 0x4800 82 | math memory_pos_02 = pos_02 83 | math pos_03 = 0x9000 84 | math memory_pos_03 = pos_03 85 | math num_01 = 0x13578642 86 | math num_02 = num_01 87 | elif bin_filename == "vp2.bin" 88 | math full_header_size = 0x9000 89 | math index_count = 0xc00 90 | math pos_01 = 0 91 | math memory_pos_01 = pos_01 92 | math pos_02 = 0x3000 93 | math memory_pos_02 = pos_02 94 | math pos_03 = 0x6000 95 | math memory_pos_03 = pos_03 96 | math num_01 = 0x49287491 97 | math num_02 = num_01 98 | endif 99 | math pos_01 + bin_offset 100 | math pos_02 + bin_offset 101 | math pos_03 + bin_offset 102 | 103 | xmath full_count "index_count >> 3" 104 | log MEMORY_FILE 0 full_header_size 105 | for i = 0 < full_count 106 | for j = 0 < 4 107 | goto pos_01 108 | get b01 long 109 | math pos_01 + 4 110 | xmath pk01 "num_01 << 1" 111 | math b01 ^ num_01 112 | goto memory_pos_01 MEMORY_FILE 113 | put b01 long MEMORY_FILE 114 | math memory_pos_01 + 4 115 | math num_01 ^ pk01 116 | goto pos_02 117 | get b02 long 118 | math pos_02 + 4 119 | math pk01 ~ num_01 120 | xmath pk02 "pk01 ^ num_02" 121 | xmath pk01 "pk02 << 2" 122 | math pk01 ^ num_02 123 | math b02 ^ num_01 124 | goto memory_pos_02 MEMORY_FILE 125 | put b02 long MEMORY_FILE 126 | math memory_pos_02 + 4 127 | goto pos_03 128 | get b03 long 129 | math pos_03 + 4 130 | math b03 ^ pk02 131 | goto memory_pos_03 MEMORY_FILE 132 | put b03 long MEMORY_FILE 133 | math memory_pos_03 + 4 134 | math pk02 ^ pk01 135 | goto pos_01 136 | get b04 long 137 | math pos_01 + 4 138 | xmath pk01 "pk02 << 1" 139 | math b04 ^ pk02 140 | goto memory_pos_01 MEMORY_FILE 141 | put b04 long MEMORY_FILE 142 | math memory_pos_01 + 4 143 | math pk02 ^ pk01 144 | goto pos_02 145 | get b05 long 146 | math pos_02 + 4 147 | math pk01 ~ pk02 148 | xmath num_01 "pk01 ^ num_02" 149 | xmath pk01 "num_01 << 2" 150 | math pk01 ^ num_02 151 | math b05 ^ pk02 152 | goto memory_pos_02 MEMORY_FILE 153 | put b05 long MEMORY_FILE 154 | math memory_pos_02 + 4 155 | goto pos_03 156 | get b06 long 157 | math pos_03 + 4 158 | math b06 ^ num_01 159 | goto memory_pos_03 MEMORY_FILE 160 | put b06 long MEMORY_FILE 161 | math memory_pos_03 + 4 162 | math num_01 ^ pk01 163 | next j 164 | next i 165 | 166 | if bin_filename == "sotet.bin" 167 | math memory_pos_01 = 0 168 | math memory_pos_02 = 0x5000 169 | math memory_pos_03 = 0xa000 170 | elif bin_filename == "radiata.bin" 171 | math memory_pos_01 = 0 172 | math memory_pos_02 = 0x4800 173 | math memory_pos_03 = 0x9000 174 | elif bin_filename == "vp2.bin" 175 | math memory_pos_01 = 0 176 | math memory_pos_02 = 0x3000 177 | math memory_pos_03 = 0x6000 178 | endif 179 | 180 | math slz_sign = 0x534c5a 181 | math sle_sign = 0x534c45 182 | for i = 0 < index_count 183 | math no_data = 0 184 | goto memory_pos_01 MEMORY_FILE 185 | get byte_01 long MEMORY_FILE 186 | math memory_pos_01 + 4 187 | goto memory_pos_02 MEMORY_FILE 188 | get byte_02 long MEMORY_FILE 189 | math memory_pos_02 + 4 190 | goto memory_pos_03 MEMORY_FILE 191 | get byte_03 long MEMORY_FILE 192 | math memory_pos_03 + 4 193 | if byte_01 = 0 194 | if byte_02 = 0 195 | if byte_03 = 0 196 | math no_data = 1 197 | endif 198 | endif 199 | endif 200 | if no_data = 0 201 | set file_type string "" 202 | set file_extension string "" 203 | math i2 = i 204 | math i2 + 1 205 | if i == 0 206 | math file_offset = bin_offset 207 | else 208 | xmath file_offset "byte_01 << 11" 209 | endif 210 | /* 211 | goto file_offset 212 | get file_sign long 213 | set file_extension string "unknown" 214 | xmath slz_sle_match "((file_sign & 0xff) << 16) | (((file_sign >> 8) & 0xff) << 8) | ((file_sign >> 16) & 0xff)" 215 | if slz_sle_match = slz_sign 216 | set file_extension string "slz" 217 | elif slz_sle_match = sle_sign 218 | set file_extension string "sle" 219 | endif 220 | if file_sign == 0 221 | get possible_datapack_01 long 222 | get possible_datapack_02 long 223 | if possible_datapack % 0x10 224 | set file_extension string "pack_01" 225 | # probably "csi" 226 | endif 227 | endif 228 | if file_sign >= 0x20 && file_sign <= 0x4e000 229 | goto 0x14 0 SEEK_CUR 230 | get possible_csd long 231 | if possible_csd == 0 || possible_csd == 1 232 | set file_extension string "csd" 233 | endif 234 | endif 235 | if file_sign == 0x594d44 236 | set file_extension string "dmy" 237 | endif 238 | if file_sign == 0x534c5a 239 | set file_extension string "zls" 240 | endif 241 | if file_sign == 0x4b434150 242 | set file_extension string "pack_02" 243 | endif 244 | if file_sign == 0x57514553 245 | set file_extension string "csm" 246 | endif 247 | if file_sign == 0x67225277 248 | set file_extension string "encrypted_pss" 249 | endif 250 | if file_sign == 0xba010000 251 | set file_extension string "pss" 252 | endif 253 | xmath file_size "byte_02 << 11" 254 | xmath runtime_file_offset "byte_03 << 11" 255 | if runtime_file_offset = 0 256 | set file_type string "miscellanea" 257 | else 258 | set file_type string "runtime" 259 | endif 260 | string temp_name p "%s/%s/%04d.%s" path_name file_type i2 file_extension 261 | log temp_name file_offset file_size 262 | */ 263 | log "" file_offset file_size 264 | endif 265 | next i 266 | endif 267 | -------------------------------------------------------------------------------- /tvdj_flk.bms: -------------------------------------------------------------------------------- 1 | # TVDJ (PS2) - *.FLK 2 | 3 | get is_flk long 4 | if is_flk != 0x034b4c46 # "FLK\x03" 5 | cleanexit 6 | endif 7 | get block_size long 8 | get info_offset long 9 | get header_size long 10 | goto info_offset 11 | for i1 = 0 < 0x1b 12 | get rec_01 short 13 | putarray 0 i rec_01 14 | get rec_02 short 15 | putarray 1 i rec_02 16 | next i1 17 | for i2 = 0 18 | get hash_01 long 19 | get hash_02 long 20 | get file_03 long 21 | get file_04 long 22 | if file_03 == 0 23 | break 24 | else 25 | xmath file_03_01 "(file_03 >> 16) & 0xffff" 26 | xmath file_03_02 "file_03 & 0xffff" 27 | putarray 0 i2 hash_01 28 | putarray 1 i2 hash_02 29 | putarray 2 i2 file_03_01 30 | putarray 3 i2 file_03_02 31 | math file_04 + header_size 32 | putarray 4 i2 file_04 33 | endif 34 | next i2 35 | math files = i2 36 | math i2 - 1 37 | for i2 = 0 < files 38 | math file_size = 0 39 | getarray hash_01 0 i2 40 | getarray hash_02 1 i2 41 | getarray file_03_01 2 i2 42 | getarray file_03_02 3 i2 43 | getarray file_04 4 i2 44 | string temp_name p "%08x_%08x." hash_01 hash_02 45 | if hash_02 != 0xff43a9af 46 | xmath i2p "i2 + 1" 47 | getarray size_aid 4 i2p 48 | xmath file_size "(size_aid - file_04) - (block_size - file_03_01)" 49 | math file_offset == file_04 50 | log temp_name file_offset file_size 51 | endif 52 | next i2 53 | -------------------------------------------------------------------------------- /ubisoft_montreal_ps2_int.bms: -------------------------------------------------------------------------------- 1 | # Ubisoft Montreal (PS2) - *.INT video files 2 | # This PS2-exclusive format was first used on Batman: Rise of Sin Tzu. 3 | 4 | open FDDE "int" 0 5 | 6 | get INT_ASIZE1 asize 7 | get INT_BNAME basename 8 | get INT_FNAME fullname 9 | get INT_SIGN long 10 | get INT01 float 11 | get INT02 long 12 | get INT03 long 13 | get INT_LAYERS long 14 | get VID1 byte 15 | get VID2 byte 16 | get AUD1 byte 17 | get AUD2 byte 18 | get INT06 long 19 | get INT07 long 20 | get INT08 long 21 | get INT09 long 22 | 23 | # this is where the script calulates the offset of the entire data. 24 | xmath INT_OFFSET1 "(INT03 * 4) + 0x2c" 25 | if INT_LAYERS == 0 26 | math INT_OFFSET1 + INT06 27 | elif INT_LAYERS == 1 28 | math INT_OFFSET1 + INT06 29 | math INT_OFFSET1 + INT08 30 | elif INT_LAYERS == 2 31 | math INT_OFFSET1 + INT06 32 | math INT08_03 = INT08 33 | math INT08_03 * INT_LAYERS 34 | math INT_OFFSET1 + INT08_03 35 | math INT_OFFSET1 + INT09 36 | elif INT_LAYERS == 5 37 | math INT_OFFSET1 + INT06 38 | math INT08_03 = INT08 39 | math INT08_03 * INT_LAYERS 40 | math INT_OFFSET1 + INT08_03 41 | endif 42 | 43 | # apparently, doing "math INT_OFFSET1 x= 0x20/0x30/0x40" yielded bad results on some files 44 | # so instead this script will find out the actual offset through a 16-time loop that uses this 45 | # 32-bit variable to see if the value reached out of that variable is zero. 46 | # if it's zero, it'll calculate INT_OFFSET1 by 4 every time it does this, otherwise it stops right there. 47 | savepos TMP2 48 | goto INT_OFFSET1 49 | for pd = 0 < 16 50 | get PADDING1 long 51 | if PADDING1 == 0 52 | math INT_OFFSET1 + 4 53 | endif 54 | next pd 55 | goto TMP2 56 | 57 | for i1 = 0 <= INT03 58 | get int_chunk_offset long 59 | putarray 1 i1 int_chunk_offset 60 | next i1 61 | 62 | # this script will attempt to locate the table data in which contains all those video chunks, 63 | # although there are *.INT files that were never seen in this structure with just the audio so this procedure 64 | # is done by default. 65 | xmath MPEG2_OFFSET "(INT03 * 4) + 0x2c" 66 | goto MPEG2_OFFSET 67 | # after that, the script will then grab relevant information regarding these chunks. 68 | getdstring MPEG2_HEADER 0x24 69 | getdstring video_intra_quantizer_matrix 0x40 70 | get video_height long 71 | get video_width long 72 | get MPEG2_03 float 73 | get MPEG2_04 long 74 | get MPEG2_05 long 75 | get full_video_size long 76 | get MPEG2_07 long 77 | get MPEG2_08 long 78 | savepos INT_FINAL_OFFSET1 79 | for m2_cc = 0 < MPEG2_05 80 | get video_chunk_offset long 81 | putarray 2 m2_cc video_chunk_offset 82 | next m2_cc 83 | putarray 2 m2_cc full_video_size 84 | math m2_cc + 1 85 | 86 | # this script will thn reuse the same method as described above, but for audio chunks as well. 87 | xmath AUDIO_OFFSET "MPEG2_OFFSET + INT06" 88 | goto AUDIO_OFFSET 89 | # if the INT_LAYERS variable value is at minimum 1, then that's where the audio chunks reside. 90 | # after that, the script will then grab relevant information regarding these chunks. 91 | if INT_LAYERS == 1 92 | math audio_array = 4 93 | if AUD1 == 1 94 | if AUD2 == 0 95 | callfunction AUD1_INFO 1 96 | math audio_array + 1 97 | endif 98 | endif 99 | elif INT_LAYERS == 2 100 | math audio_array = 4 101 | if AUD1 == 1 102 | if AUD2 == 1 103 | log MEMORY_FILE2 AUDIO_OFFSET INT09 104 | get SUB_SIZE asize MEMORY_FILE2 105 | string SUB_NAME p "%s.sub" INT_BNAME 106 | log SUB_NAME 0 SUB_SIZE MEMORY_FILE2 107 | 108 | xmath AUDIO_OFFSET2 "AUDIO_OFFSET + INT09" 109 | goto AUDIO_OFFSET2 110 | for int_l2 = 0 < INT_LAYERS 111 | callfunction AUD1_INFO 1 112 | math audio_array + 1 113 | next int_l2 114 | endif 115 | endif 116 | elif INT_LAYERS == 5 117 | math audio_array = 4 118 | for int_l2 = 0 < INT_LAYERS 119 | callfunction AUD1_INFO 1 120 | math audio_array + 1 121 | next int_l2 122 | endif 123 | 124 | # after all of this whole "reading" process, all of these "number of chunks" as gathered by the script 125 | # will then be formed into one single variable consisting of not only a quantity consisting of video chunks, 126 | # but also the number of audio chunks if they exist. 127 | xmath int_total_layers "INT03 + 1" 128 | 129 | math current_video_index = 0 130 | math current_audio_index = 0 131 | math last_int_chunk_index = i1 132 | math last_video_index = m2_cc 133 | math last_audio_track_index = audio_array 134 | for ti = 0 < int_total_layers 135 | log MEMORY_FILE 0 0 136 | getarray int_chunk_offset 1 ti 137 | xmath next_int_chunk_index "ti + 1" 138 | if next_int_chunk_index != last_int_chunk_index 139 | getarray next_chunk_offset 1 next_int_chunk_index 140 | xmath int_chunk_size "next_chunk_offset - int_chunk_offset" 141 | else 142 | math int_chunk_size = 0 143 | endif 144 | math int_overall_chunk_offset = int_chunk_offset 145 | math int_overall_chunk_offset + INT_OFFSET1 146 | log MEMORY_FILE int_overall_chunk_offset int_chunk_size 147 | math chunk_offset_on_memory = 0 148 | append 149 | for v1 = 0 < 5 150 | string video_chunk_filename p "%s.m2v" INT_BNAME 151 | if current_video_index != last_video_index 152 | getarray video_chunk_offset 2 current_video_index 153 | xmath next_video_index "current_video_index + 1" 154 | if next_video_index != last_video_index 155 | getarray next_chunk_offset 2 next_video_index 156 | xmath video_chunk_size "next_chunk_offset - video_chunk_offset" 157 | else 158 | math video_chunk_size = 0 159 | endif 160 | log video_chunk_filename chunk_offset_on_memory video_chunk_size MEMORY_FILE 161 | math chunk_offset_on_memory + video_chunk_size 162 | math current_video_index + 1 163 | else 164 | break 165 | endif 166 | next v1 167 | append 168 | if INT_LAYERS != 0 169 | math chunk_offset_on_memory = chunk_offset_on_memory 170 | append 171 | for a1 = 4 < last_audio_track_index 172 | xmath a2 "(a1 - 4) + 1" 173 | string audio_chunk_filename p "[%02d]%s.ubs" a2 INT_BNAME 174 | getarray last_audio_index 3 a1 175 | xmath penultimate_audio_track "last_audio_track_index - 1" 176 | if current_audio_index != last_audio_index 177 | getarray audio_chunk_offset a1 current_audio_index 178 | xmath next_audio_index "current_audio_index + 1" 179 | if next_audio_index != last_audio_index 180 | getarray next_chunk_offset a1 next_audio_index 181 | xmath audio_chunk_size "next_chunk_offset - audio_chunk_offset" 182 | else 183 | math audio_chunk_size = 0 184 | endif 185 | log audio_chunk_filename chunk_offset_on_memory audio_chunk_size MEMORY_FILE 186 | math chunk_offset_on_memory + audio_chunk_size 187 | if a1 = penultimate_audio_track 188 | math current_audio_index + 1 189 | endif 190 | else 191 | break 192 | endif 193 | next a1 194 | append 195 | endif 196 | next ti 197 | 198 | # in this kind of structure, there's no way to accurately tell which codec format is which 199 | # but for all I know the codecs used for these *.INT video files look like this: 200 | # 1. Ubisoft 4-bit IMA ADPCM 201 | # 2. 16-bit PCM(little-endian) 202 | startfunction AUD1_INFO 203 | get AUD1_01 long 204 | get AUD1_02 long 205 | get AUD1_03 long 206 | get AUD1_04 long 207 | get AUD1_05 long 208 | xmath AUD1_06 "(INT08 / 4) - 5" 209 | putarray 3 audio_array AUD1_06 210 | for a1_cc = 0 < AUD1_06 211 | get audio_chunk_offset long 212 | putarray audio_array a1_cc audio_chunk_offset 213 | next a1_cc 214 | endfunction 215 | -------------------------------------------------------------------------------- /ubisoft_sra.bms: -------------------------------------------------------------------------------- 1 | # Ubisoft - *.SRA 2 | # --- 3 | # Naruto: Rise of a Ninja 4 | # Naruto: The Broken Bond 5 | 6 | comtype zlib 7 | 8 | get sra_id long 9 | if sra_id != 0x41535246 # "ASRF"(LE) 10 | cleanexit 11 | endif 12 | get sra_version long 13 | get sra_info_off_01 long 14 | get sra_entries_01 long 15 | get sra_info_off_02 long 16 | get sra_entries_02 long 17 | 18 | goto sra_info_off_01 19 | for i = 0 < sra_entries_01 20 | get e1_1 long 21 | putarray 0 i e1_1 22 | get e1_2 long 23 | putarray 1 i e1_2 24 | get e1_3 long 25 | putarray 2 i e1_3 26 | get e1_4 long 27 | putarray 3 i e1_4 28 | get e1_5 long 29 | putarray 4 i e1_5 30 | get e1_6 long 31 | putarray 5 i e1_6 32 | get e1_7 long 33 | putarray 6 i e1_7 34 | next i 35 | 36 | goto sra_info_off_02 37 | for i = 0 < sra_entries_02 38 | get e2_1 long 39 | putarray 7 i e2_1 40 | get e2_2 long 41 | putarray 8 i e2_2 42 | if e2_1 == 0 43 | get e2_3 long 44 | putarray 9 i e2_3 45 | get e2_4 long 46 | putarray 10 i e2_4 47 | elif e2_1 == 1 48 | get e2_3 long 49 | putarray 9 i e2_3 50 | getdstring e2_4 0x80 51 | putarray 10 i e2_4 52 | endif 53 | next i 54 | 55 | for i = 0 < sra_entries_01 56 | set file_name string "" 57 | getarray entry_type 0 i 58 | getarray entry_id 1 i 59 | getarray entry_hash 2 i 60 | getarray entry_offset 3 i 61 | getarray compressed_file_size 4 i 62 | getarray original_file_size 5 i 63 | getarray entry_07 6 i 64 | for i2 = 0 < sra_entries_02 65 | getarray matching_hash 9 i2 66 | if entry_id == matching_hash 67 | getarray sub_type_01 7 i2 68 | getarray sub_type_02 8 i2 69 | if sub_type_01 == 0 70 | getarray eh1 9 i2 71 | getarray eh2 10 i2 72 | string file_name p "[%u]%08x_%08x[%08x]." entry_offset eh1 eh2 entry_hash 73 | else 74 | getarray eh1 9 i2 75 | getarray file_name 10 i2 76 | endif 77 | break 78 | endif 79 | next i2 80 | if original_file_size == 0 81 | log file_name entry_offset compressed_file_size 82 | else 83 | clog file_name entry_offset compressed_file_size original_file_size 84 | endif 85 | next i 86 | -------------------------------------------------------------------------------- /valve_vpk.bms: -------------------------------------------------------------------------------- 1 | # Valve - vpk 2 | # --- 3 | # also used in some Source engine games made not only by Valve itself 4 | # but also by people outside Valve, see this Wikipedia article for a "entire" list of them: 5 | # https://en.wikipedia.org/wiki/Source_(game_engine) 6 | # there's also this Steam group who collects Steam games that use said engine 7 | # https://steamcommunity.com/groups/sourceenginegames 8 | 9 | get dir_file filename 10 | set base_file string dir_file 11 | string base_file - "_dir.vpk" 12 | get sign_01 long 13 | if sign_01 != 0x55aa1234 14 | cleanexit 15 | endif 16 | get sign_02 long 17 | xmath major_version "sign_02 & 0xffff" 18 | if major_version != 2 19 | cleanexit 20 | endif 21 | xmath minor_version "(sign_02 >> 16) & 0xffff" 22 | string version_display p "%01d.%01d" major_version minor_version 23 | print " Valve VPK filesystem version %version_display% " 24 | get dir_size long 25 | if major_version == 1 26 | print " VPK version 1 not supported, contact me to request support for your file within this script. " 27 | cleanexit 28 | endif 29 | if major_version == 2 30 | get vpk_03 long 31 | endif 32 | if minor_version == 0 33 | # everything else 34 | get md5_size_01 long 35 | get md5_size_02 long 36 | get sig_size long 37 | endif 38 | if minor_version == 3 39 | # Titanfall (2014) 40 | # Titanfall 2 (2016) 41 | putarray 0 0 "none" 42 | putarray 0 1 "english" 43 | putarray 0 2 "german" 44 | putarray 0 3 "french" 45 | putarray 0 4 "italian" 46 | putarray 0 5 "korean" 47 | putarray 0 6 "spanish" 48 | putarray 0 7 "schinese" 49 | putarray 0 8 "tchinese" 50 | putarray 0 9 "russian" 51 | putarray 0 10 "thai" 52 | putarray 0 11 "japanese" 53 | putarray 0 12 "portuguese" 54 | putarray 0 13 "polish" 55 | putarray 0 14 "danish" 56 | putarray 0 15 "dutch" 57 | putarray 0 16 "finnish" 58 | putarray 0 17 "norwegian" 59 | putarray 0 18 "swedish" 60 | putarray 0 19 "czech" 61 | putarray 0 20 "hungarian" 62 | putarray 0 21 "romanian" 63 | putarray 0 22 "turkish" 64 | math folders = 0 65 | math files = 0 66 | math chunks_per_file = 0 67 | set sc1 string "" 68 | set sc2 string "" 69 | for i = 0 < 1 70 | if i = 0 71 | for j = 0 < 23 72 | getarray language_name 0 j 73 | string base_file - language_name 74 | next j 75 | endif 76 | next i 77 | endif 78 | for i = 0 79 | get extension string 80 | if extension == "" 81 | break 82 | else 83 | math folders = 1 84 | for j = 0 < folders 85 | get path string 86 | if path == "" 87 | break 88 | else 89 | math files = 1 90 | for k = 0 < files 91 | get name string 92 | get file_01 long 93 | get file_02 short 94 | if name != "" 95 | string file_name p "%s/%s.%s" path name extension 96 | print "%file_name%" 97 | if minor_version == 0 98 | get pak_number short 99 | if pak_number != 0x7fff 100 | string pak_name p "%s_%03d.vpk" base_file pak_number 101 | open FDSE pak_name 1 102 | endif 103 | get file_offset long 104 | get file_size long 105 | if pak_number != 0x7fff 106 | log file_name file_offset file_size 1 107 | else 108 | math file_offset + 0x1c 109 | math file_offset + dir_size 110 | log file_name file_offset file_size 111 | endif 112 | endif 113 | if minor_version == 3 114 | math chunks_per_file = 1 115 | append 116 | for l = 0 < chunks_per_file 117 | get pak_number short 118 | if pak_number == 0xffff 119 | # wonky work-around for some Titanfall 2 vpk files 120 | goto -2 0 SEEK_CUR 121 | break 122 | endif 123 | string pak_name p "%s_%03d.vpk" base_file pak_number 124 | open FDSE pak_name 1 125 | get file_04 byte 126 | get file_05 byte 127 | get file_06 long 128 | get file_offset_from_pak_number longlong 129 | get compressed_chunk_size longlong 130 | get original_chunk_size longlong 131 | if original_chunk_size = 0x100000 132 | math chunks_per_file + 1 133 | endif 134 | if compressed_chunk_size == original_chunk_size 135 | log file_name file_offset_from_pak_number original_chunk_size 1 136 | else 137 | # (todo) Titanfall uses a (to the best of my knowledge) 138 | # proprietary compression algorithm, not lzham. 139 | #clog file_name file_offset_from_pak_number compressed_chunk_size original_chunk_size 1 140 | #log file_name file_offset_from_pak_number compressed_chunk_size 1 141 | endif 142 | next l 143 | append 144 | endif 145 | get delimiter short 146 | if delimiter != 0xffff 147 | break 148 | endif 149 | endif 150 | get extra byte 151 | if extra == 0 152 | math folders + 1 153 | else 154 | goto -1 0 SEEK_CUR 155 | math files + 1 156 | endif 157 | next k 158 | endif 159 | next j 160 | endif 161 | next i 162 | -------------------------------------------------------------------------------- /virtuos_vbf.bms: -------------------------------------------------------------------------------- 1 | # Virtuos - *.vbf 2 | # or "VirtuosBigFile" as known through FFXX-2_LAUNCHER.exe 3 | # --- 4 | # Final Fantasy X/X-2 HD Remaster(PC) 5 | # Final Fantasy XII The Zodiac Age(PC) 6 | # --- 7 | # "rewritten" from aluigi's ffxhd.bms script 8 | 9 | math ram = 0 10 | # set this (^) to 1 for a MEMORY_FILE extraction process 11 | 12 | comtype zlib_noerror 13 | idstring "SRYK" 14 | get sryk_headersize long 15 | get files long 16 | get zero long 17 | math sryk_off2 = 0x10 18 | xmath sryk_off3 "(files * 0x10) + sryk_off2" 19 | xmath sryk_off4 "(files * 0x20) + sryk_off3" 20 | xmath sryk_off5 "sryk_off4 + 4" 21 | goto sryk_off4 22 | get sryk_namesize long 23 | xmath sryk_fcoff1 "sryk_off4 + sryk_namesize" 24 | 25 | for i = 0 < files 26 | savepos sryk_tmp1 27 | goto sryk_off2 28 | getdstring md5_hash 0x10 29 | goto sryk_off3 30 | get idx1 long 31 | get idx2 long 32 | get size longlong 33 | get offset longlong 34 | get name_off longlong 35 | 36 | math name_off += sryk_off5 37 | goto name_off 38 | get name string 39 | 40 | xmath sryk_fcoff2 "sryk_fcoff1 + (idx1 * 2)" 41 | xmath chunks "(size / 0x10000) + 1" 42 | goto sryk_fcoff2 43 | 44 | if ram = 1 45 | putvarchr MEMORY_FILE size 0 46 | log MEMORY_FILE 0 0 47 | endif 48 | 49 | append 50 | for x = 0 < chunks 51 | get chunk_size short 52 | if chunk_size == 0 53 | math chunk_size = 0x10000 54 | endif 55 | if ram = 0 56 | clog name offset chunk_size 0x10000 57 | elif ram = 1 58 | clog MEMORY_FILE offset chunk_size 0x10000 59 | endif 60 | math offset + chunk_size 61 | next x 62 | append 63 | 64 | if ram = 1 65 | log name 0 size MEMORY_FILE 66 | endif 67 | 68 | math sryk_off2 += 0x10 69 | math sryk_off3 += 0x20 70 | goto sryk_tmp1 71 | next i 72 | -------------------------------------------------------------------------------- /x3_zpk.bms: -------------------------------------------------------------------------------- 1 | # X-Men: The Official Game (PlayStation 2, Xbox, Xbox 360) - X3.ZPK 2 | # --- 3 | # this script covers the "bigfile" format used in only this game. maybe. 4 | # this format takes advantage of like 4 indexes, only the second one is needed 5 | # to actually access the files. 6 | # the rest is treated in a fairly straightforward order (1->3->4) 7 | # for as long as the structure of the 2nd index is still being dealt with. 8 | # not to mention, there can be as many duplicates of a file stored within 9 | # the so-called "zpack" file (which is the ZPK file you're looking at) as possible. 10 | # said duplicates can have actual offset values for them, to the point of 11 | # padding out a "zpack" for more than necessary. 12 | # this script doesn't deal with all these duplicates. 13 | 14 | get x3_zpk filename 15 | if x3_zpk != "X3.ZPK" 16 | cleanexit 17 | endif 18 | 19 | get zpk_size asize 20 | xmath zpk_info_offset "zpk_size - 2048" 21 | goto zpk_info_offset 22 | get zpk_01 long # 0 23 | get zpk_02 long # 1 24 | get zpk_03 long # 2 25 | get zpk_04 long # weird value that can range from 0x2bd0 to 0x2c62 26 | for i = 0 < 4 27 | get entry_info_size long 28 | putarray 0 i entry_info_size 29 | get entry_info_offset long 30 | putarray 1 i entry_info_offset 31 | next i 32 | get entries long 33 | get zpk_06 long # 1 34 | get zpk_07 long # 3 35 | 36 | getarray overall_file_info_entries 0 0 37 | getarray overall_file_info_offset 1 0 38 | getarray b1 0 1 # weird value here, like 0x142601 39 | getarray overall_file_id_info_offset 1 1 40 | getarray individual_file_name_depot_size 0 2 41 | getarray individual_file_name_depot_offset 1 2 42 | log MEMORY_FILE individual_file_name_depot_offset individual_file_name_depot_size 43 | getarray individual_file_offset_depot_size 0 3 44 | getarray individual_file_offset_depot_offset 1 3 45 | log MEMORY_FILE2 individual_file_offset_depot_offset individual_file_offset_depot_size 46 | goto overall_file_id_info_offset 47 | for i = 0 < entries 48 | get file_id short 49 | if file_id != 0xffff 50 | xmath individual_file_info_offset "(file_id * 0x18) + 4" 51 | # ^ "plus 4" is needed. otherwise the script might parse the file info at a wrong position. 52 | math individual_file_info_offset + overall_file_info_offset 53 | savepos tmp_01 54 | goto individual_file_info_offset 55 | get individual_file_name_offset long 56 | goto individual_file_name_offset MEMORY_FILE 57 | get file_name string MEMORY_FILE 58 | get file_size long 59 | get file_duplicates longlong 60 | get file_offset_id longlong 61 | xmath file_offset_offset "file_offset_id * 4" 62 | goto file_offset_offset MEMORY_FILE2 63 | get file_offset long MEMORY_FILE2 64 | log file_name file_offset file_size 65 | goto tmp_01 66 | endif 67 | next i 68 | -------------------------------------------------------------------------------- /zone_of_the_enders.bms: -------------------------------------------------------------------------------- 1 | get zoe_dat_size asize 2 | 3 | math byte_size = 0x20 4 | callfunction hashing_algorithm 1 5 | 6 | math zoe_dat_ver = 0 7 | 8 | if result == 0x0496db6a 9 | # zoe.dat - TGS2000 10 | math zoe_dat_ver = 1 11 | elif result == 0x12db7aa8 12 | # zoe.dat - retail 13 | math zoe_dat_ver = 2 14 | else 15 | string show_hash p "0x%08x" result 16 | print " this script has a built-in hashing algorithm system in place \n so it can generate fingerprints as to which ZOE.DAT will this script work with. \n \n alas, this ZOE.DAT file doesn't work with this generated fingerprint - %show_hash% " 17 | break 18 | endif 19 | 20 | math entry = 0 21 | math last_entry = 0 22 | math entries = -1 23 | math entry_info_offset = 0 24 | math backup_entries_01 = 0 25 | math backup_entries_02 = 0 26 | math backup_info_offset_01 = 0 27 | math backup_info_offset_02 = 0 28 | math current_backup_entry_01 = 0 29 | math current_backup_entry_02 = 0 30 | math naming_type = 0 31 | math backup_name_number = 0 32 | math current_name_number = 0 33 | for entry = entry != entries 34 | set file_name_per_entry string "" 35 | set entry_name string "" 36 | xmath last_entry "entries - 1" 37 | goto entry_info_offset 38 | getdstring entry_info 0x20 39 | math entry_info_offset += 0x20 40 | math backup_info_offset_01 == entry_info_offset 41 | math current_name_number + 1 42 | getvarchr temp_01 entry_info 0x10 long 43 | getvarchr temp_02 entry_info 0x14 long 44 | if zoe_dat_ver = 2 45 | getvarchr entry_flags entry_info 0x18 long 46 | endif 47 | if temp_01 == 0 || temp_02 == 0 48 | math naming_type = 1 49 | else 50 | math naming_type = 2 51 | endif 52 | if naming_type = 1 53 | for char = 0 < 8 54 | getvarchr string_byte entry_info char byte 55 | string string_char = string_byte 56 | if string_byte != 0 57 | string entry_name + string_char 58 | endif 59 | next char 60 | math current_name_number - 1 61 | if zoe_dat_ver = 1 62 | math backup_name_number = current_name_number 63 | math backup_entries_01 == entries 64 | math current_backup_entry_01 == entry 65 | getvarchr directory_value_01 entry_info 0x08 long 66 | math entries == directory_value_01 67 | math entries + 1 68 | getvarchr directory_value_02 entry_info 0x0c long 69 | math entry_info_offset == directory_value_02 70 | math entry == 0 71 | elif zoe_dat_ver = 2 72 | if entry_flags == 0x102 73 | math backup_name_number = current_name_number 74 | math backup_entries_01 == entries 75 | math current_backup_entry_01 == entry 76 | getvarchr directory_value_01 entry_info 0x08 long 77 | math entries == directory_value_01 78 | math entries + 1 79 | getvarchr directory_value_02 entry_info 0x0c long 80 | math entry_info_offset == directory_value_02 81 | math entry == 0 82 | endif 83 | endif 84 | elif naming_type = 2 85 | for char = 0 < 16 86 | getvarchr string_byte entry_info char byte 87 | string string_char = string_byte 88 | if string_byte != 0 89 | string entry_name + string_char 90 | endif 91 | next char 92 | if zoe_dat_ver = 1 93 | if entry_name & "." 94 | if entry > 1 95 | math current_name_number - 1 96 | endif 97 | getvarchr file_offset_per_entry entry_info 0x10 long 98 | xmath file_offset_per_entry "(file_offset_per_entry - 0x18) << 11" 99 | getvarchr file_size_per_entry entry_info 0x14 long 100 | else 101 | math backup_name_number = current_name_number 102 | math backup_entries_02 == entries 103 | math current_backup_entry_02 == entry 104 | math backup_info_offset_02 == backup_info_offset_01 105 | getvarchr directory_value_03 entry_info 0x10 long 106 | math entries == directory_value_03 107 | math entries + 1 108 | getvarchr directory_value_04 entry_info 0x14 long 109 | xmath entry_info_offset "(directory_value_04 - 0x18) << 11" 110 | if entry_name == "fa1" 111 | xmath directory_info_limit "entry_info_offset + ((entries - 3) * 0x20)" 112 | elif entry_name == "title" 113 | xmath directory_info_limit "entry_info_offset + ((entries - 2) * 0x20)" 114 | else 115 | xmath directory_info_limit "entry_info_offset + ((entries - 1) * 0x20)" 116 | endif 117 | math entry == 0 118 | endif 119 | elif zoe_dat_ver = 2 120 | if entry_flags == 0 121 | if entry > 1 122 | math current_name_number - 1 123 | endif 124 | getvarchr file_offset_per_entry entry_info 0x10 long 125 | math file_offset_per_entry << 11 126 | getvarchr file_size_per_entry entry_info 0x14 long 127 | elif entry_flags == 0x102 128 | math backup_name_number = current_name_number 129 | math backup_entries_02 == entries 130 | math current_backup_entry_02 == entry 131 | math backup_info_offset_02 == backup_info_offset_01 132 | getvarchr directory_value_03 entry_info 0x10 long 133 | math entries == directory_value_03 134 | math entries + 1 135 | getvarchr directory_value_04 entry_info 0x14 long 136 | xmath entry_info_offset "directory_value_04 << 11" 137 | math entry == 0 138 | endif 139 | endif 140 | endif 141 | putarray 1 current_name_number entry_name 142 | math name_list = current_name_number 143 | for j = 0 <= name_list 144 | getarray entry_name 1 j 145 | string file_name_per_entry + entry_name 146 | if j != name_list 147 | string file_name_per_entry + / 148 | endif 149 | next j 150 | if zoe_dat_ver = 1 151 | if file_name_per_entry & "." 152 | log file_name_per_entry file_offset_per_entry file_size_per_entry 153 | endif 154 | elif zoe_dat_ver = 2 155 | if entry_flags == 0 156 | log file_name_per_entry file_offset_per_entry file_size_per_entry 157 | endif 158 | endif 159 | if zoe_dat_ver = 1 160 | if naming_type = 1 161 | if entry == last_entry 162 | math current_name_number - backup_name_number 163 | math entries == backup_entries_01 164 | math entry == current_backup_entry_01 165 | math entry_info_offset == backup_info_offset_01 166 | endif 167 | elif naming_type = 2 168 | if entry_info_offset = directory_info_limit 169 | math current_name_number - backup_name_number 170 | math entries == backup_entries_02 171 | math entry == current_backup_entry_02 172 | math entry_info_offset == backup_info_offset_02 173 | endif 174 | endif 175 | elif zoe_dat_ver = 2 176 | if entry == last_entry 177 | if naming_type = 1 178 | math current_name_number - backup_name_number 179 | math entries == backup_entries_01 180 | math entry == current_backup_entry_01 181 | math entry_info_offset == backup_info_offset_01 182 | elif naming_type = 2 183 | math current_name_number - backup_name_number 184 | math entries == backup_entries_02 185 | math entry == current_backup_entry_02 186 | math entry_info_offset == backup_info_offset_02 187 | endif 188 | endif 189 | endif 190 | next entry 191 | 192 | startfunction hashing_algorithm 193 | math hash = 0 194 | math result = 0 195 | for i = 0 < byte_size 196 | get overall_byte byte 197 | xmath hash "hash + ((hash << (overall_byte & 0x0f)) | (hash >> 3) + (overall_byte << (char & 0x0f)) + overall_byte)" 198 | next i 199 | math result = hash 200 | endfunction 201 | --------------------------------------------------------------------------------