├── .gitignore ├── README.md ├── build_fonts.sh ├── build_localization.sh ├── data └── files_list.txt ├── fonts └── fonts.json ├── get_strings.sh ├── omegat └── files_order.txt ├── prepare.sh ├── prepare_fonts.sh └── tools ├── astcenc-avx2 ├── astcenc-avx2.exe ├── clone_kernings.py ├── convert_texture.sh ├── format ├── bin.py ├── charnames.py ├── dat.py ├── ftb.py ├── ktb.py ├── mcd.py ├── pak.py ├── properties.py ├── smd.py ├── tmd.py ├── utils.py └── wta.py ├── get_strings.py ├── put_glyphs.py ├── put_strings.py ├── put_strings_mcd.py ├── repack_dat.py ├── repack_wtp.py ├── swizzle.py ├── unpack_dat.py ├── unpack_dds.py └── unpack_font.py /.gitignore: -------------------------------------------------------------------------------- 1 | data/ 2 | unpacked/ 3 | source/ 4 | fonts/ 5 | assembly/ 6 | target/ 7 | output/ 8 | __pycache__ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nier: Automata Localization Tool 2 | 3 | Toolset for creating unofficial localization of Nier: Automata 4 | 5 | ## Getting Started 6 | 7 | These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. 8 | 9 | ### Prerequisites 10 | 11 | * Bash 12 | * Python 3.6 (or newer) 13 | * ImageMagick 14 | 15 | ### Setup 16 | 17 | 1. Create [OmegaT](https://omegat.org/) project 18 | 2. Copy files from this repo to the OmegaT project 19 | 3. Unpack CRI packages from the game to `data/` directory. ([CriPakGUI](https://github.com/wmltogether/CriPakTools/releases) can be used) 20 | 4. Run `./prepare.sh` to unpack files and generate `source/` directory (this should be done only once) 21 | 5. Fonts 22 | 1. Add missing characters in `fonts/`. Name of the character should be codepoint number as a 4-digit hex, e.g. `017a.png` for 23 | letter 'ź' (Latin Small Letter Z with Acute). 24 | 2. Edit `./build_fonts.sh` to add missing characters 25 | 2. Run `./build_fonts.sh` to generate font files 26 | 6. Translation 27 | 1. Translate files and generate `target/` directory in OmegaT 28 | 2. Run `./build_localization.sh` to generate `output/` 29 | 7. Copy files from `output/` to `/data/` 30 | 31 | ### Directories structure 32 | 33 | * `omegat/` - files used by OmegaT 34 | * `data/` - \*.dat and \*.dtt files extracted from CRI packages (\*.cpk) 35 | * `fonts/` - font data - glyph images 36 | * `unpacked/` - untranslated raw files (\*.bin, \*.mcd, \*.smd, etc.) extracted from \*.dat and \*.dtt files. \*.dds textures are also extracted 37 | * `source/` - source \*.properties and \*.txt files for translation 38 | * `target/` - \*.properties and \*.txt files translated to target language 39 | * `assembly/` - translated raw files (\*.bin, \*.mcd, \*.smd, etc.) 40 | * `output/` - translated \*.dat and \*.dtt files 41 | 42 | ### Notes 43 | 44 | OmegaT is not handling properly values in .properties files ending with backslash. Value `key=\\` is interpreted as escaping endline 45 | rather than escaped backslash. For that reason dummy value `` is added. It should be removed during translation. 46 | 47 | Glyphs for some of the fonts have color data in transparent parts. Some image editors will lose this information when exporting to PNG. 48 | Losing this data will cause these characters to render incorrectly. To get around this following ImageMagick commands can be used: 49 | ``` 50 | convert glyph.png -alpha extract glyph_alpha.png # extract alpha channel 51 | convert glyph.png -alpha off glyph_color.png # extract color channels 52 | convert glyph_color.png glyph_alpha.png -alpha off -compose CopyOpacity -composite glyph.png # combine alpha and color 53 | ``` 54 | 55 | ## Acknowledgments 56 | 57 | Resources used during development: 58 | * Russian translations by Rindera (https://steamcommunity.com/sharedfiles/filedetails/?id=1206296158) and The Miracle (https://steamcommunity.com/sharedfiles/filedetails/?id=889954753) 59 | * General information on files formats: https://forum.xentax.com/viewtopic.php?t=16011 60 | * DAT format: https://gist.github.com/Wunkolo/213aa61eb0c874172aec97ebb8ab89c2 and https://github.com/xxk-i/DATrepacker/blob/master/dat_utils.py 61 | * MCD format: https://zenhax.com/viewtopic.php?t=1502&p=8181 and https://github.com/Kerilk/bayonetta_tools/tree/master/binary_templates 62 | * WTA format: https://github.com/Kerilk/bayonetta_tools/blob/master/binary_templates/Nier%20Automata%20wta.bt 63 | * mruby bytecode: https://github.com/mrubyc/mrubyc/ and https://github.com/mruby/mruby/ 64 | -------------------------------------------------------------------------------- /build_fonts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function build_font() { 4 | echo "building font ${1}" 5 | 6 | mkdir -p assembly/font/font_${1}.dat/ 7 | mkdir -p assembly/font/font_${1}.dtt/ 8 | mkdir -p output/font/ 9 | mkdir -p output/font/ 10 | 11 | if stat unpacked/font/font_${1}.dtt/*.astc >/dev/null 2>&1; then 12 | TGT_TEX_EXT=astc 13 | else 14 | TGT_TEX_EXT=dds 15 | fi 16 | 17 | N=$((`ls unpacked/font/font_${1}.dtt/*.dds | wc -l` - 1)) 18 | 19 | # add ĄąĆćĘꣳŃńŚśŹźŻż 20 | ./tools/put_glyphs.py unpacked/font/font_${1}.dat/font_${1}.ftb unpacked/font/font_${1}.dtt/font_${1}.wtp_00${N}.dds \ 21 | assembly/font/font_${1}.dat/font_${1}.ftb assembly/font/font_${1}.dtt/font_${1}.wtp_00${N}.png --page ${N} \ 22 | --char $((16#0104)) fonts/${1}/0104.png \ 23 | --char $((16#0105)) fonts/${1}/0105.png \ 24 | --char $((16#0106)) fonts/${1}/0106.png \ 25 | --char $((16#0107)) fonts/${1}/0107.png \ 26 | --char $((16#0118)) fonts/${1}/0118.png \ 27 | --char $((16#0119)) fonts/${1}/0119.png \ 28 | --char $((16#0141)) fonts/${1}/0141.png \ 29 | --char $((16#0142)) fonts/${1}/0142.png \ 30 | --char $((16#0143)) fonts/${1}/0143.png \ 31 | --char $((16#0144)) fonts/${1}/0144.png \ 32 | --char $((16#015a)) fonts/${1}/015a.png \ 33 | --char $((16#015b)) fonts/${1}/015b.png \ 34 | --char $((16#0179)) fonts/${1}/0179.png \ 35 | --char $((16#017a)) fonts/${1}/017a.png \ 36 | --char $((16#017b)) fonts/${1}/017b.png \ 37 | --char $((16#017c)) fonts/${1}/017c.png 38 | 39 | ./tools/convert_texture.sh assembly/font/font_${1}.dtt/font_${1}.wtp_00${N}.png assembly/font/font_${1}.dtt/font_${1}.wtp_00${N}.${TGT_TEX_EXT} 40 | 41 | # add ĄąĆćĘęŃńŚśŹźŻż (skip Ł and ł) 42 | if [ -e unpacked/font/font_${1}.dat/font_${1}.ktb ] 43 | then 44 | ./tools/clone_kernings.py unpacked/font/font_${1}.dat/font_${1}.ktb assembly/font/font_${1}.dat/font_${1}.ktb \ 45 | --char $((16#0041)) $((16#0104)) \ 46 | --char $((16#0061)) $((16#0105)) \ 47 | --char $((16#0043)) $((16#0106)) \ 48 | --char $((16#0063)) $((16#0107)) \ 49 | --char $((16#0045)) $((16#0118)) \ 50 | --char $((16#0065)) $((16#0119)) \ 51 | --char $((16#004E)) $((16#0143)) \ 52 | --char $((16#006E)) $((16#0144)) \ 53 | --char $((16#0053)) $((16#015a)) \ 54 | --char $((16#0073)) $((16#015b)) \ 55 | --char $((16#005A)) $((16#0179)) \ 56 | --char $((16#007A)) $((16#017a)) \ 57 | --char $((16#005A)) $((16#017b)) \ 58 | --char $((16#007A)) $((16#017c)) 59 | fi 60 | 61 | ./tools/repack_wtp.py unpacked/font/font_${1}.dat/font_${1}.wta unpacked/font/font_${1}.dtt/font_${1}.wtp \ 62 | --texture ${N} assembly/font/font_${1}.dtt/font_${1}.wtp_00${N}.${TGT_TEX_EXT} \ 63 | assembly/font/font_${1}.dat/font_${1}.wta assembly/font/font_${1}.dtt/font_${1}.wtp 64 | 65 | ./tools/repack_dat.py data/font/font_${1}.dat output/font/font_${1}.dat assembly/font/font_${1}.dat/* 66 | ./tools/repack_dat.py data/font/font_${1}.dtt output/font/font_${1}.dtt assembly/font/font_${1}.dtt/*.wtp 67 | } 68 | 69 | build_font 00 70 | build_font 01 71 | build_font 04 72 | build_font 05 73 | build_font 11 74 | -------------------------------------------------------------------------------- /build_localization.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #empty LANG2 and LANG3 are for jp 4 | LANG2="_us" # _fr _it _de _es 5 | LANG3="_eng" # _fra _ita _ger _esp 6 | TLANG="_pl" # language suffix from 7 | 8 | function put_strings() { 9 | DAT_FILE=${1} 10 | NAME=${2} 11 | EXT=${3} 12 | echo "building ${NAME}" 13 | 14 | if [[ ${EXT} == "txt" ]]; then 15 | mkdir -p output/novel 16 | cp target/${NAME}.${EXT} output/novel/${NAME}.${EXT} 17 | elif [[ ${EXT} == "mcd" ]]; then 18 | DTT_FILE=${DAT_FILE/.dat/.dtt} 19 | mkdir -p assembly/${DAT_FILE}/ 20 | mkdir -p assembly/${DTT_FILE}/ 21 | ./tools/put_strings_mcd.py unpacked/${DAT_FILE}/${NAME}.mcd target/${NAME}${TLANG}.properties fonts/fonts.json assembly/${DAT_FILE}/${NAME}.mcd assembly/${DTT_FILE}/${NAME}.wtp_000.png 22 | 23 | if stat unpacked/${DTT_FILE}/*.astc >/dev/null 2>&1; then 24 | TGT_TEX_EXT=astc 25 | else 26 | TGT_TEX_EXT=dds 27 | fi 28 | 29 | ./tools/convert_texture.sh assembly/${DTT_FILE}/${NAME}.wtp_000.png assembly/${DTT_FILE}/${NAME}.wtp_000.${TGT_TEX_EXT} 30 | ./tools/repack_wtp.py unpacked/${DAT_FILE}/${NAME}.wta unpacked/${DTT_FILE}/${NAME}.wtp assembly/${DAT_FILE}/${NAME}.wta assembly/${DTT_FILE}/${NAME}.wtp --texture 0 assembly/${DTT_FILE}/${NAME}.wtp_000.${TGT_TEX_EXT} 31 | 32 | mkdir -p `dirname output/${DAT_FILE}` 33 | mkdir -p `dirname output/${DTT_FILE}` 34 | ./tools/repack_dat.py data/${DAT_FILE} output/${DAT_FILE} assembly/${DAT_FILE}/* 35 | ./tools/repack_dat.py data/${DTT_FILE} output/${DTT_FILE} assembly/${DTT_FILE}/${NAME}.wtp 36 | else 37 | mkdir -p assembly/${DAT_FILE}/ 38 | ./tools/put_strings.py unpacked/${DAT_FILE}/${NAME}.${EXT} target/${NAME}${TLANG}.properties assembly/${DAT_FILE}/${NAME}.${EXT} 39 | if [[ ${EXT} == "tmd" || ${EXT} == "smd" ]]; then 40 | mkdir -p `dirname output/${DAT_FILE}` 41 | ./tools/repack_dat.py data/${DAT_FILE} output/${DAT_FILE} assembly/${DAT_FILE}/${NAME}.${EXT} 42 | fi 43 | fi 44 | 45 | } 46 | 47 | function repack_dat() { 48 | mkdir -p `dirname output/${1}` 49 | ./tools/repack_dat.py data/${1} output/${1} assembly/${1}/* 50 | } 51 | 52 | put_strings core/corehap.dat global_d595bcd1_scp bin 53 | put_strings core/corehap.dat global_60efb803_scp bin 54 | put_strings core/corehap.dat global_638e40c8_scp bin 55 | put_strings core/corehap.dat core_hap pak; repack_dat core/corehap.dat 56 | put_strings ph1/p100.dat p100_fa238e7c_scp bin 57 | put_strings ph1/p100.dat p100_c6ab1d8f_scp bin 58 | put_strings ph1/p100.dat p100_dfcc155d_scp bin 59 | put_strings ph1/p100.dat p100_7f31f924_scp bin 60 | put_strings ph1/p100.dat p100_d8a4a747_scp bin 61 | put_strings ph1/p100.dat p100_e1dc4db4_scp bin 62 | put_strings ph1/p100.dat p100_e2d39d13_scp bin 63 | put_strings ph1/p100.dat p100_440fda42_scp bin 64 | put_strings ph1/p100.dat p100_536bd4fb_scp bin 65 | put_strings ph1/p100.dat p100_7c282dc8_scp bin 66 | put_strings ph1/p100.dat p100_cbfd7706_scp bin 67 | put_strings ph1/p100.dat p100_6a34d49e_scp bin 68 | put_strings ph1/p100.dat p100_301b50d3_scp bin 69 | put_strings ph1/p100.dat p100_5f2b7c58_scp bin 70 | put_strings ph1/p100.dat p100_a85f65ec_scp bin 71 | put_strings ph1/p100.dat p100_10a1b8c_scp bin 72 | put_strings ph1/p100.dat p100_8371cfcf_scp bin 73 | put_strings ph1/p100.dat p100_54edd5c_scp bin 74 | put_strings ph1/p100.dat p100_ce928ad9_scp bin 75 | put_strings ph1/p100.dat p100_89910ddf_scp bin 76 | put_strings ph1/p100.dat p100_a5817204_scp bin 77 | put_strings ph1/p100.dat p100_6695192d_scp bin 78 | put_strings ph1/p100.dat p100_4aa7dace_scp bin 79 | put_strings ph1/p100.dat p100_43f203b8_scp bin 80 | put_strings ph1/p100.dat p100_90998b13_scp bin 81 | put_strings ph1/p100.dat p100_973474b4_scp bin 82 | put_strings ph1/p100.dat p100_69ab2de6_scp bin 83 | put_strings ph1/p100.dat p100_643b9449_scp bin 84 | put_strings ph1/p100.dat p100_306867fd_scp bin 85 | put_strings ph1/p100.dat p100_61b598fd_scp bin 86 | put_strings ph1/p100.dat p100_39cda07a_scp bin 87 | put_strings ph1/p100.dat p100_9092a1f1_scp bin 88 | put_strings ph1/p100.dat p100_1a401b0f_scp bin 89 | put_strings ph1/p100.dat p100_ec82f9bf_scp bin 90 | put_strings ph1/p100.dat p100_cb2621f3_scp bin 91 | put_strings ph1/p100.dat p100_56f39801_scp bin 92 | put_strings ph1/p100.dat p100_6fc2accc_scp bin 93 | put_strings ph1/p100.dat p100_824dfa10_scp bin 94 | put_strings ph1/p100.dat p100_508c029e_scp bin 95 | put_strings ph1/p100.dat p100_a2a7da53_scp bin 96 | put_strings ph1/p100.dat p100_23622eee_scp bin 97 | put_strings ph1/p100.dat p100_56e518db_scp bin 98 | put_strings ph1/p100.dat p100_2299a056_scp bin 99 | put_strings ph1/p100.dat p100_73ce9cac_scp bin 100 | put_strings ph1/p100.dat p100_adc09aec_scp bin 101 | put_strings ph1/p100.dat p100_81c8f672_scp bin 102 | put_strings ph1/p100.dat p100_47a5d6eb_scp bin 103 | put_strings ph1/p100.dat p100_9b15340d_scp bin 104 | put_strings ph1/p100.dat p100_264b174c_scp bin; repack_dat ph1/p100.dat 105 | put_strings ph2/p200.dat p200_a2a7da53_scp bin 106 | put_strings ph2/p200.dat p200_2e8bdcb0_scp bin 107 | put_strings ph2/p200.dat p200_886c2178_scp bin 108 | put_strings ph2/p200.dat p200_92dddd6e_scp bin 109 | put_strings ph2/p200.dat p200_bb51fdfc_scp bin 110 | put_strings ph2/p200.dat p200_b99094bd_scp bin 111 | put_strings ph2/p200.dat p200_20084f1f_scp bin 112 | put_strings ph2/p200.dat p200_a3d6d2f5_scp bin 113 | put_strings ph2/p200.dat p200_7c0c6f18_scp bin 114 | put_strings ph2/p200.dat p200_c544d6ad_scp bin 115 | put_strings ph2/p200.dat p200_78334de1_scp bin 116 | put_strings ph2/p200.dat p200_24125524_scp bin 117 | put_strings ph2/p200.dat p200_7398bbfd_scp bin 118 | put_strings ph2/p200.dat p200_24194e13_scp bin 119 | put_strings ph2/p200.dat p200_647d1cd7_scp bin 120 | put_strings ph2/p200.dat p200_3c562f91_scp bin 121 | put_strings ph2/p200.dat p200_ff3d446f_scp bin 122 | put_strings ph2/p200.dat p200_d0b71b3b_scp bin 123 | put_strings ph2/p200.dat p200_71c59d9f_scp bin 124 | put_strings ph2/p200.dat p200_8cbb3f1e_scp bin 125 | put_strings ph2/p200.dat p200_2bfce9ed_scp bin 126 | put_strings ph2/p200.dat p200_48a7f0fd_scp bin 127 | put_strings ph2/p200.dat p200_6ae550e0_scp bin 128 | put_strings ph2/p200.dat p200_96e13a06_scp bin 129 | put_strings ph2/p200.dat p200_ad4026af_scp bin 130 | put_strings ph2/p200.dat p200_8182a35a_scp bin 131 | put_strings ph2/p200.dat p200_27db07bb_scp bin 132 | put_strings ph2/p200.dat p200_20cd934d_scp bin 133 | put_strings ph2/p200.dat p200_5dfcaace_scp bin 134 | put_strings ph2/p200.dat p200_e723b449_scp bin 135 | put_strings ph2/p200.dat p200_a1e11071_scp bin 136 | put_strings ph2/p200.dat p200_e8fce7cc_scp bin 137 | put_strings ph2/p200.dat p200_4b245f40_scp bin 138 | put_strings ph2/p200.dat p200_c7ba8911_scp bin 139 | put_strings ph2/p200.dat p200_f764463b_scp bin 140 | put_strings ph2/p200.dat p200_a68c4ea9_scp bin 141 | put_strings ph2/p200.dat p200_e8cf2a5c_scp bin 142 | put_strings ph2/p200.dat p200_58623dde_scp bin 143 | put_strings ph2/p200.dat p200_d5ac1e7d_scp bin 144 | put_strings ph2/p200.dat p200_1cc100aa_scp bin 145 | put_strings ph2/p200.dat p200_398cde2c_scp bin 146 | put_strings ph2/p200.dat p200_f1f22ca2_scp bin 147 | put_strings ph2/p200.dat p200_aad478cc_scp bin 148 | put_strings ph2/p200.dat p200_7914bf_scp bin 149 | put_strings ph2/p200.dat p200_c44b75b3_scp bin 150 | put_strings ph2/p200.dat p200_b4fc12d6_scp bin 151 | put_strings ph2/p200.dat p200_1fcb850d_scp bin 152 | put_strings ph2/p200.dat p200_67909aeb_scp bin 153 | put_strings ph2/p200.dat p200_8806bcb7_scp bin 154 | put_strings ph2/p200.dat p200_7793b6d6_scp bin 155 | put_strings ph2/p200.dat p200_17d05835_scp bin 156 | put_strings ph2/p200.dat p200_99454795_scp bin 157 | put_strings ph2/p200.dat p200_56645a4b_scp bin 158 | put_strings ph2/p200.dat p200_9a8a8724_scp bin 159 | put_strings ph2/p200.dat p200_8767f81e_scp bin 160 | put_strings ph2/p200.dat p200_40b3c93d_scp bin 161 | put_strings ph2/p200.dat p200_c3ab84c7_scp bin 162 | put_strings ph2/p200.dat p200_d0a7f4dc_scp bin 163 | put_strings ph2/p200.dat p200_cc694d55_scp bin 164 | put_strings ph2/p200.dat p200_7a5876f7_scp bin 165 | put_strings ph2/p200.dat p200_d75fa9d2_scp bin 166 | put_strings ph2/p200.dat p200_dad50fa7_scp bin 167 | put_strings ph2/p200.dat p200_9dd3606e_scp bin 168 | put_strings ph2/p200.dat p200_6aa3f28e_scp bin 169 | put_strings ph2/p200.dat p200_2311697b_scp bin 170 | put_strings ph2/p200.dat p200_1de99b24_scp bin 171 | put_strings ph2/p200.dat p200_3456f87_scp bin 172 | put_strings ph2/p200.dat p200_8118914c_scp bin 173 | put_strings ph2/p200.dat p200_5a63902e_scp bin 174 | put_strings ph2/p200.dat p200_2fb68036_scp bin; repack_dat ph2/p200.dat 175 | put_strings ph3/p300.dat p300_f80fe22d_scp bin 176 | put_strings ph3/p300.dat p300_abb1d768_scp bin 177 | put_strings ph3/p300.dat p300_69ab2de6_scp bin 178 | put_strings ph3/p300.dat p300_fe415e44_scp bin 179 | put_strings ph3/p300.dat p300_e9106cc6_scp bin 180 | put_strings ph3/p300.dat p300_a60ff1fc_scp bin 181 | put_strings ph3/p300.dat p300_d578eca9_scp bin 182 | put_strings ph3/p300.dat p300_26ad4903_scp bin 183 | put_strings ph3/p300.dat p300_8352dd61_scp bin 184 | put_strings ph3/p300.dat p300_1cc46857_scp bin 185 | put_strings ph3/p300.dat p300_a34d9d8a_scp bin 186 | put_strings ph3/p300.dat p300_2ac25a34_scp bin 187 | put_strings ph3/p300.dat p300_e47baab_scp bin 188 | put_strings ph3/p300.dat p300_73ee82d4_scp bin 189 | put_strings ph3/p300.dat p300_1c94bbb3_scp bin 190 | put_strings ph3/p300.dat p300_969b4cd4_scp bin 191 | put_strings ph3/p300.dat p300_52095a27_scp bin 192 | put_strings ph3/p300.dat p300_5f56e621_scp bin 193 | put_strings ph3/p300.dat p300_d7fb6a72_scp bin 194 | put_strings ph3/p300.dat p300_a80afa1d_scp bin 195 | put_strings ph3/p300.dat p300_58e3f469_scp bin 196 | put_strings ph3/p300.dat p300_b863f435_scp bin 197 | put_strings ph3/p300.dat p300_4ac43a7f_scp bin 198 | put_strings ph3/p300.dat p300_f29af5ee_scp bin 199 | put_strings ph3/p300.dat p300_59a32047_scp bin 200 | put_strings ph3/p300.dat p300_ebb2aa60_scp bin 201 | put_strings ph3/p300.dat p300_2b0332c8_scp bin 202 | put_strings ph3/p300.dat p300_8f18b72c_scp bin 203 | put_strings ph3/p300.dat p300_78ebd792_scp bin 204 | put_strings ph3/p300.dat p300_4fce2323_scp bin 205 | put_strings ph3/p300.dat p300_abb0feab_scp bin 206 | put_strings ph3/p300.dat p300_7677d46d_scp bin 207 | put_strings ph3/p300.dat p300_33eec348_scp bin 208 | put_strings ph3/p300.dat p300_312ca323_scp bin 209 | put_strings ph3/p300.dat p300_b01535dd_scp bin 210 | put_strings ph3/p300.dat p300_6f88066d_scp bin 211 | put_strings ph3/p300.dat p300_454d3c27_scp bin 212 | put_strings ph3/p300.dat p300_fb6b9581_scp bin 213 | put_strings ph3/p300.dat p300_838131a5_scp bin 214 | put_strings ph3/p300.dat p300_540e0da_scp bin 215 | put_strings ph3/p300.dat p300_e3d05ab7_scp bin 216 | put_strings ph3/p300.dat p300_dd8b37bd_scp bin 217 | put_strings ph3/p300.dat p300_9d8df164_scp bin 218 | put_strings ph3/p300.dat p300_af5fb37c_scp bin 219 | put_strings ph3/p300.dat p300_d48627b4_scp bin 220 | put_strings ph3/p300.dat p300_34ffac43_scp bin 221 | put_strings ph3/p300.dat p300_2460bab4_scp bin 222 | put_strings ph3/p300.dat p300_fe580523_scp bin 223 | put_strings ph3/p300.dat p300_be18477d_scp bin 224 | put_strings ph3/p300.dat p300_7220e53d_scp bin 225 | put_strings ph3/p300.dat p300_79a7d0d0_scp bin 226 | put_strings ph3/p300.dat p300_cc42e29e_scp bin 227 | put_strings ph3/p300.dat p300_d86d80b1_scp bin 228 | put_strings ph3/p300.dat p300_fb5ab100_scp bin 229 | put_strings ph3/p300.dat p300_62973173_scp bin 230 | put_strings ph3/p300.dat p300_249dcf6a_scp bin 231 | put_strings ph3/p300.dat p300_f0e6bd59_scp bin 232 | put_strings ph3/p300.dat p300_95a183ba_scp bin 233 | put_strings ph3/p300.dat p300_24fd47f4_scp bin 234 | put_strings ph3/p300.dat p300_50eb25b8_scp bin 235 | put_strings ph3/p300.dat p300_ac91bbe4_scp bin 236 | put_strings ph3/p300.dat p300_d913dcc1_scp bin 237 | put_strings ph3/p300.dat p300_df90c81a_scp bin 238 | put_strings ph3/p300.dat p300_54b1765c_scp bin 239 | put_strings ph3/p300.dat p300_9b77492c_scp bin 240 | put_strings ph3/p300.dat p300_4a0a3acc_scp bin 241 | put_strings ph3/p300.dat p300_157c0c19_scp bin 242 | put_strings ph3/p300.dat p300_802d17e9_scp bin 243 | put_strings ph3/p300.dat p300_fca61b8d_scp bin 244 | put_strings ph3/p300.dat p300_544f9315_scp bin 245 | put_strings ph3/p300.dat p300_987be645_scp bin 246 | put_strings ph3/p300.dat p300_68b9c234_scp bin 247 | put_strings ph3/p300.dat p300_10112854_scp bin 248 | put_strings ph3/p300.dat p300_d2ca712b_scp bin 249 | put_strings ph3/p300.dat p300_7de5c329_scp bin 250 | put_strings ph3/p300.dat p300_f4f38872_scp bin 251 | put_strings ph3/p300.dat p300_4716685f_scp bin 252 | put_strings ph3/p300.dat p300_e6cf440a_scp bin 253 | put_strings ph3/p300.dat p300_22633b31_scp bin 254 | put_strings ph3/p300.dat p300_ae2eada6_scp bin 255 | put_strings ph3/p300.dat p300_d2de713_scp bin 256 | put_strings ph3/p300.dat p300_c0c1e86c_scp bin 257 | put_strings ph3/p300.dat p300_e4c7a829_scp bin; repack_dat ph3/p300.dat 258 | put_strings ph4/p400.dat p400_b0e38442_scp bin 259 | put_strings ph4/p400.dat p400_fc21ced3_scp bin 260 | put_strings ph4/p400.dat p400_3af366c3_scp bin 261 | put_strings ph4/p400.dat p400_5b4661f4_scp bin 262 | put_strings ph4/p400.dat p400_42374ea5_scp bin 263 | put_strings ph4/p400.dat p400_1afc5db6_scp bin 264 | put_strings ph4/p400.dat p400_5489214b_scp bin; repack_dat ph4/p400.dat 265 | put_strings phf/pf10.dat pf10_7de5c329_scp bin; repack_dat phf/pf10.dat 266 | put_strings phf/pf30.dat pf30_148bec7a_scp bin; repack_dat phf/pf30.dat 267 | put_strings phf/pf31.dat pf31_d2ca712b_scp bin; repack_dat phf/pf31.dat 268 | put_strings phf/pf60.dat pf60_149e7cbe_scp bin; repack_dat phf/pf60.dat 269 | put_strings quest/q020.dat q020_404eba3d_scp bin; repack_dat quest/q020.dat 270 | put_strings quest/q031.dat q031_b551328a_scp bin; repack_dat quest/q031.dat 271 | put_strings quest/q032.dat q032_94bdfeb7_scp bin; repack_dat quest/q032.dat 272 | put_strings quest/q040.dat q040_cf7c14d9_scp bin; repack_dat quest/q040.dat 273 | put_strings quest/q070.dat q070_fb360535_scp bin; repack_dat quest/q070.dat 274 | put_strings quest/q071.dat q071_1a17171a_scp bin; repack_dat quest/q071.dat 275 | put_strings quest/q080.dat q080_64afc72a_scp bin; repack_dat quest/q080.dat 276 | put_strings quest/q090.dat q090_11b12a94_scp bin 277 | put_strings quest/q090.dat q090_86062922_scp bin 278 | put_strings quest/q090.dat q090_105d4edd_scp bin; repack_dat quest/q090.dat 279 | put_strings quest/q091.dat q091_def6c866_scp bin 280 | put_strings quest/q091.dat q091_402dfd2e_scp bin 281 | put_strings quest/q091.dat q091_e03615dd_scp bin 282 | put_strings quest/q091.dat q091_2f2a0eea_scp bin; repack_dat quest/q091.dat 283 | put_strings quest/q092.dat q092_3cd7f934_scp bin 284 | put_strings quest/q092.dat q092_35330df_scp bin 285 | put_strings quest/q092.dat q092_82c2e878_scp bin; repack_dat quest/q092.dat 286 | put_strings quest/q095.dat q095_fc4d3b85_scp bin; repack_dat quest/q095.dat 287 | put_strings quest/q100.dat q100_f4f7e973_scp bin; repack_dat quest/q100.dat 288 | put_strings quest/q101.dat q101_5be5b4cc_scp bin; repack_dat quest/q101.dat 289 | put_strings quest/q102.dat q102_28e223f7_scp bin; repack_dat quest/q102.dat 290 | put_strings quest/q103.dat q103_d2b3f5a6_scp bin; repack_dat quest/q103.dat 291 | put_strings quest/q104.dat q104_e9ff21ee_scp bin; repack_dat quest/q104.dat 292 | put_strings quest/q110.dat q110_171236f0_scp bin; repack_dat quest/q110.dat 293 | put_strings quest/q120.dat q120_8dcd7a1a_scp bin; repack_dat quest/q120.dat 294 | put_strings quest/q121.dat q121_70545c1f_scp bin; repack_dat quest/q121.dat 295 | put_strings quest/q122.dat q122_3a5128c8_scp bin; repack_dat quest/q122.dat 296 | put_strings quest/q123.dat q123_6fde04e_scp bin; repack_dat quest/q123.dat 297 | put_strings quest/q130.dat q130_b68bfe22_scp bin; repack_dat quest/q130.dat 298 | put_strings quest/q140.dat q140_7cda31e_scp bin; repack_dat quest/q140.dat 299 | put_strings quest/q150.dat q150_d31e5833_scp bin; repack_dat quest/q150.dat 300 | put_strings quest/q160.dat q160_d8b9d0be_scp bin; repack_dat quest/q160.dat 301 | put_strings quest/q162.dat q162_fc7da4a2_scp bin; repack_dat quest/q162.dat 302 | put_strings quest/q170.dat q170_96333b78_scp bin; repack_dat quest/q170.dat 303 | put_strings quest/q171.dat q171_12f2963a_scp bin; repack_dat quest/q171.dat 304 | put_strings quest/q180.dat q180_2d2126d2_scp bin; repack_dat quest/q180.dat 305 | put_strings quest/q181.dat q181_746d944f_scp bin; repack_dat quest/q181.dat 306 | put_strings quest/q210.dat q210_a6306d6c_scp bin; repack_dat quest/q210.dat 307 | put_strings quest/q220.dat q220_e880784a_scp bin; repack_dat quest/q220.dat 308 | put_strings quest/q221.dat q221_b113244a_scp bin; repack_dat quest/q221.dat 309 | put_strings quest/q222.dat q222_f8217e42_scp bin; repack_dat quest/q222.dat 310 | put_strings quest/q290.dat q290_e15f2fa1_scp bin; repack_dat quest/q290.dat 311 | put_strings quest/q300.dat q300_5f9ed04e_scp bin; repack_dat quest/q300.dat 312 | put_strings quest/q330.dat q330_21f485e_scp bin 313 | put_strings quest/q330.dat q330_70a701da_scp bin 314 | put_strings quest/q330.dat q330_9bafd382_scp bin 315 | put_strings quest/q330.dat q330_b853020f_scp bin 316 | put_strings quest/q330.dat q330_ee317264_scp bin; repack_dat quest/q330.dat 317 | put_strings quest/q340.dat q340_5620eb59_scp bin; repack_dat quest/q340.dat 318 | put_strings quest/q360.dat q360_8efed5ef_scp bin; repack_dat quest/q360.dat 319 | put_strings quest/q400.dat q400_1f6199eb_scp bin 320 | put_strings quest/q400.dat q400_21ca35cb_scp bin 321 | put_strings quest/q400.dat q400_48d76c20_scp bin 322 | put_strings quest/q400.dat q400_fc5b48ad_scp bin; repack_dat quest/q400.dat 323 | put_strings quest/q401.dat q401_643e5418_scp bin; repack_dat quest/q401.dat 324 | put_strings quest/q403.dat q403_5d43ba8b_scp bin; repack_dat quest/q403.dat 325 | put_strings quest/q410.dat q410_4f2b901a_scp bin; repack_dat quest/q410.dat 326 | put_strings quest/q440.dat q440_3b4ef61d_scp bin; repack_dat quest/q440.dat 327 | put_strings quest/q500.dat q500_8446c06e_scp bin; repack_dat quest/q500.dat 328 | put_strings quest/q520.dat q520_afd5aa67_scp bin; repack_dat quest/q520.dat 329 | put_strings quest/q532.dat q532_65ff89bf_scp bin; repack_dat quest/q532.dat 330 | put_strings quest/q540.dat q540_e1207097_scp bin; repack_dat quest/q540.dat 331 | put_strings quest/q550.dat q550_688e8050_scp bin; repack_dat quest/q550.dat 332 | put_strings quest/q560.dat q560_291dbe71_scp bin; repack_dat quest/q560.dat 333 | put_strings quest/q561.dat q561_74b9a716_scp bin; repack_dat quest/q561.dat 334 | put_strings quest/q562.dat q562_e10ec9ab_scp bin; repack_dat quest/q562.dat 335 | put_strings quest/q590.dat q590_13ffe891_scp bin; repack_dat quest/q590.dat 336 | put_strings quest/q640.dat q640_ccd60068_scp bin; repack_dat quest/q640.dat 337 | put_strings quest/q650.dat q650_96497077_scp bin; repack_dat quest/q650.dat 338 | put_strings quest/q651.dat q651_87a1f20b_scp bin; repack_dat quest/q651.dat 339 | put_strings quest/q652.dat q652_4e20ab43_scp bin; repack_dat quest/q652.dat 340 | put_strings quest/q660.dat q660_f737718_scp bin; repack_dat quest/q660.dat 341 | put_strings quest/q680.dat q680_51d704e4_scp bin; repack_dat quest/q680.dat 342 | put_strings quest/q720.dat q720_bbe0d32e_scp bin; repack_dat quest/q720.dat 343 | put_strings quest/q770.dat q770_59f68d25_scp bin; repack_dat quest/q770.dat 344 | put_strings quest/q800.dat q800_bc7a2755_scp bin; repack_dat quest/q800.dat 345 | put_strings quest/q801.dat q801_6c8f629a_scp bin; repack_dat quest/q801.dat 346 | put_strings quest/q900.dat q900_626a2689_scp bin; repack_dat quest/q900.dat 347 | put_strings quest/q910.dat q910_8d8ebfae_scp bin; repack_dat quest/q910.dat 348 | put_strings quest/q920.dat q920_e5072c9_scp bin; repack_dat quest/q920.dat 349 | put_strings quest/qab2.dat qab2_aec178b7_scp bin; repack_dat quest/qab2.dat 350 | put_strings quest/qab3.dat qab3_934fd3b1_scp bin; repack_dat quest/qab3.dat 351 | put_strings quest/qab5.dat qab5_4a1ea1bc_scp bin; repack_dat quest/qab5.dat 352 | put_strings quest/qab6.dat qab6_69325679_scp bin; repack_dat quest/qab6.dat 353 | put_strings quest/qaba.dat qaba_a7ed1850_scp bin; repack_dat quest/qaba.dat 354 | put_strings quest/qabb.dat qabb_1e5a233e_scp bin; repack_dat quest/qabb.dat 355 | put_strings quest/qabd.dat qabd_18ca8961_scp bin; repack_dat quest/qabd.dat 356 | put_strings quest/qac8.dat qac8_fd8ac7ea_scp bin; repack_dat quest/qac8.dat 357 | put_strings quest/qad0.dat qad0_c493efec_scp bin; repack_dat quest/qad0.dat 358 | put_strings quest/qad1.dat qad1_55fcb9b3_scp bin; repack_dat quest/qad1.dat 359 | put_strings quest/qad2.dat qad2_e6ef8eaf_scp bin; repack_dat quest/qad2.dat 360 | put_strings quest/qad6.dat qad6_b6255483_scp bin; repack_dat quest/qad6.dat 361 | put_strings quest/qaeb.dat qaeb_98b8e891_scp bin; repack_dat quest/qaeb.dat 362 | put_strings quest/qaef.dat qaef_10112854_scp bin; repack_dat quest/qaef.dat 363 | put_strings quest/qaf4.dat qaf4_e04e13b1_scp bin; repack_dat quest/qaf4.dat 364 | put_strings quest/qb20.dat qb20_42c8efa_scp bin 365 | put_strings quest/qb20.dat qb20_91cf1fa5_scp bin; repack_dat quest/qb20.dat 366 | put_strings quest/qb40.dat qb40_f2a5ded9_scp bin 367 | put_strings quest/qb40.dat qb40_b490bdc_scp bin 368 | put_strings quest/qb40.dat qb40_ff6d92e9_scp bin 369 | put_strings quest/qb40.dat qb40_9403a9bc_scp bin 370 | put_strings quest/qb40.dat qb40_f7708d83_scp bin; repack_dat quest/qb40.dat 371 | put_strings quest/qc10.dat qc10_ea55109b_scp bin; repack_dat quest/qc10.dat 372 | put_strings quest/qc11.dat qc11_e05e7f97_scp bin; repack_dat quest/qc11.dat 373 | put_strings quest/qc12.dat qc12_9b9e9b86_scp bin; repack_dat quest/qc12.dat 374 | put_strings quest/qc30.dat qc30_fde14379_scp bin; repack_dat quest/qc30.dat 375 | put_strings quest/qc50.dat qc50_de375136_scp bin; repack_dat quest/qc50.dat 376 | put_strings st1/r100.dat r100_c723351a_scp bin; repack_dat st1/r100.dat 377 | put_strings st1/r110.dat r110_be7ebe38_scp bin 378 | put_strings st1/r110.dat r110_6b1cbecb_scp bin 379 | put_strings st1/r110.dat r110_4ebc3b22_scp bin 380 | put_strings st1/r110.dat r110_7fe2a715_scp bin 381 | put_strings st1/r110.dat r110_7a562cb9_scp bin 382 | put_strings st1/r110.dat r110_dd7422a2_scp bin; repack_dat st1/r110.dat 383 | put_strings st1/r120.dat r120_f0d26b5d_scp bin; repack_dat st1/r120.dat 384 | put_strings st1/r130.dat r130_e5cfdb23_scp bin 385 | put_strings st1/r130.dat r130_12b5a85a_scp bin; repack_dat st1/r130.dat 386 | put_strings st1/r140.dat r140_29cb90b_scp bin 387 | put_strings st1/r140.dat r140_60377331_scp bin 388 | put_strings st1/r140.dat r140_82d2caac_scp bin 389 | put_strings st1/r140.dat r140_cd4fd96a_scp bin 390 | put_strings st1/r140.dat r140_f82d8b66_scp bin 391 | put_strings st1/r140.dat r140_657c1219_scp bin 392 | put_strings st1/r140.dat r140_7e0bd84f_scp bin 393 | put_strings st1/r140.dat r140_9fbdc6a2_scp bin 394 | put_strings st1/r140.dat r140_dc76121c_scp bin 395 | put_strings st1/r140.dat r140_ea0da2aa_scp bin 396 | put_strings st1/r140.dat r140_336c5af9_scp bin 397 | put_strings st1/r140.dat r140_49e73635_scp bin; repack_dat st1/r140.dat 398 | put_strings st1/r150.dat r150_5ced6cf8_scp bin 399 | put_strings st1/r150.dat r150_f100866e_scp bin 400 | put_strings st1/r150.dat r150_df579346_scp bin; repack_dat st1/r150.dat 401 | put_strings st1/r160.dat r160_3fa0647a_scp bin 402 | put_strings st1/r160.dat r160_74d9b777_scp bin 403 | put_strings st1/r160.dat r160_1557ce81_scp bin 404 | put_strings st1/r160.dat r160_7247f0a7_scp bin 405 | put_strings st1/r160.dat r160_307c8a44_scp bin 406 | put_strings st1/r160.dat r160_f8f21cd2_scp bin 407 | put_strings st1/r160.dat r160_19656865_scp bin 408 | put_strings st1/r160.dat r160_e290faf0_scp bin 409 | put_strings st1/r160.dat r160_dc20cee5_scp bin 410 | put_strings st1/r160.dat r160_441c44e3_scp bin 411 | put_strings st1/r160.dat r160_7cde1b3f_scp bin; repack_dat st1/r160.dat 412 | put_strings st1/r170.dat r170_e7cef294_scp bin 413 | put_strings st1/r170.dat r170_261956fa_scp bin; repack_dat st1/r170.dat 414 | put_strings st2/r200.dat r200_427ea0a7_scp bin 415 | put_strings st2/r200.dat r200_d52e3bf5_scp bin 416 | put_strings st2/r200.dat r200_e684ee2d_scp bin 417 | put_strings st2/r200.dat r200_c832af28_scp bin 418 | put_strings st2/r200.dat r200_d4dad831_scp bin; repack_dat st2/r200.dat 419 | put_strings st5/r530.dat r530_3c8107d_scp bin; repack_dat st5/r530.dat 420 | put_strings subtitle/subtitle0010${LANG2}.dat subtitle0010 smd 421 | put_strings subtitle/subtitle0011${LANG2}.dat subtitle0011 smd 422 | put_strings subtitle/subtitle0030${LANG2}.dat subtitle0030 smd 423 | put_strings subtitle/subtitle0031${LANG2}.dat subtitle0031 smd 424 | put_strings subtitle/subtitle0040${LANG2}.dat subtitle0040 smd 425 | put_strings subtitle/subtitle0050${LANG2}.dat subtitle0050 smd 426 | put_strings subtitle/subtitle0055${LANG2}.dat subtitle0055 smd 427 | put_strings subtitle/subtitle0060${LANG2}.dat subtitle0060 smd 428 | put_strings subtitle/subtitle0080${LANG2}.dat subtitle0080 smd 429 | put_strings subtitle/subtitle0081${LANG2}.dat subtitle0081 smd 430 | put_strings subtitle/subtitle0086${LANG2}.dat subtitle0086 smd 431 | put_strings subtitle/subtitle0090${LANG2}.dat subtitle0090 smd 432 | put_strings subtitle/subtitle0091${LANG2}.dat subtitle0091 smd 433 | put_strings subtitle/subtitle0092${LANG2}.dat subtitle0092 smd 434 | put_strings subtitle/subtitle0110${LANG2}.dat subtitle0110 smd 435 | put_strings subtitle/subtitle0111${LANG2}.dat subtitle0111 smd 436 | put_strings subtitle/subtitle0120${LANG2}.dat subtitle0120 smd 437 | put_strings subtitle/subtitle0130${LANG2}.dat subtitle0130 smd 438 | put_strings subtitle/subtitle0140${LANG2}.dat subtitle0140 smd 439 | put_strings subtitle/subtitle0160${LANG2}.dat subtitle0160 smd 440 | put_strings subtitle/subtitle0170${LANG2}.dat subtitle0170 smd 441 | put_strings subtitle/subtitle0190${LANG2}.dat subtitle0190 smd 442 | put_strings subtitle/subtitle0191${LANG2}.dat subtitle0191 smd 443 | put_strings subtitle/subtitle0225${LANG2}.dat subtitle0225 smd 444 | put_strings subtitle/subtitle0226${LANG2}.dat subtitle0226 smd 445 | put_strings subtitle/subtitle0230${LANG2}.dat subtitle0230 smd 446 | put_strings subtitle/subtitle0240${LANG2}.dat subtitle0240 smd 447 | put_strings subtitle/subtitle0241${LANG2}.dat subtitle0241 smd 448 | put_strings subtitle/subtitle0250${LANG2}.dat subtitle0250 smd 449 | put_strings subtitle/subtitle0251${LANG2}.dat subtitle0251 smd 450 | put_strings subtitle/subtitle0260${LANG2}.dat subtitle0260 smd 451 | put_strings subtitle/subtitle0262${LANG2}.dat subtitle0262 smd 452 | put_strings subtitle/subtitle0270${LANG2}.dat subtitle0270 smd 453 | put_strings subtitle/subtitle0280${LANG2}.dat subtitle0280 smd 454 | put_strings subtitle/subtitle0300${LANG2}.dat subtitle0300 smd 455 | put_strings subtitle/subtitle0301${LANG2}.dat subtitle0301 smd 456 | put_strings subtitle/subtitle0310${LANG2}.dat subtitle0310 smd 457 | put_strings subtitle/subtitle0311${LANG2}.dat subtitle0311 smd 458 | put_strings subtitle/subtitle0320${LANG2}.dat subtitle0320 smd 459 | put_strings subtitle/subtitle0321${LANG2}.dat subtitle0321 smd 460 | put_strings subtitle/subtitle0322${LANG2}.dat subtitle0322 smd 461 | put_strings subtitle/subtitle0323${LANG2}.dat subtitle0323 smd 462 | put_strings subtitle/subtitle0325${LANG2}.dat subtitle0325 smd 463 | put_strings subtitle/subtitle0326${LANG2}.dat subtitle0326 smd 464 | put_strings subtitle/subtitle0330${LANG2}.dat subtitle0330 smd 465 | put_strings subtitle/subtitle0340${LANG2}.dat subtitle0340 smd 466 | put_strings subtitle/subtitle0341${LANG2}.dat subtitle0341 smd 467 | put_strings subtitle/subtitle0350${LANG2}.dat subtitle0350 smd 468 | put_strings subtitle/subtitle0351${LANG2}.dat subtitle0351 smd 469 | put_strings subtitle/subtitle0352${LANG2}.dat subtitle0352 smd 470 | put_strings subtitle/subtitle0360${LANG2}.dat subtitle0360 smd 471 | put_strings subtitle/subtitle0370${LANG2}.dat subtitle0370 smd 472 | put_strings subtitle/subtitle0390${LANG2}.dat subtitle0390 smd 473 | put_strings subtitle/subtitle0400${LANG2}.dat subtitle0400 smd 474 | put_strings subtitle/subtitle0410${LANG2}.dat subtitle0410 smd 475 | put_strings subtitle/subtitle0420${LANG2}.dat subtitle0420 smd 476 | put_strings subtitle/subtitle0440${LANG2}.dat subtitle0440 smd 477 | put_strings subtitle/subtitle0441${LANG2}.dat subtitle0441 smd 478 | put_strings subtitle/subtitle0460${LANG2}.dat subtitle0460 smd 479 | put_strings subtitle/subtitle0461${LANG2}.dat subtitle0461 smd 480 | put_strings subtitle/subtitle0470${LANG2}.dat subtitle0470 smd 481 | put_strings subtitle/subtitle0471${LANG2}.dat subtitle0471 smd 482 | put_strings subtitle/subtitle0475${LANG2}.dat subtitle0475 smd 483 | put_strings subtitle/subtitle0480${LANG2}.dat subtitle0480 smd 484 | put_strings subtitle/subtitle0482${LANG2}.dat subtitle0482 smd 485 | put_strings subtitle/subtitle0483${LANG2}.dat subtitle0483 smd 486 | put_strings subtitle/subtitle0485${LANG2}.dat subtitle0485 smd 487 | put_strings subtitle/subtitle0490${LANG2}.dat subtitle0490 smd 488 | put_strings subtitle/subtitle0491${LANG2}.dat subtitle0491 smd 489 | put_strings subtitle/subtitle0500${LANG2}.dat subtitle0500 smd 490 | put_strings subtitle/subtitle0502${LANG2}.dat subtitle0502 smd 491 | put_strings subtitle/subtitle0520${LANG2}.dat subtitle0520 smd 492 | put_strings subtitle/subtitle0521${LANG2}.dat subtitle0521 smd 493 | put_strings subtitle/subtitle0525${LANG2}.dat subtitle0525 smd 494 | put_strings subtitle/subtitle0526${LANG2}.dat subtitle0526 smd 495 | put_strings subtitle/subtitle0530${LANG2}.dat subtitle0530 smd 496 | put_strings subtitle/subtitle0531${LANG2}.dat subtitle0531 smd 497 | put_strings subtitle/subtitle0540${LANG2}.dat subtitle0540 smd 498 | put_strings subtitle/subtitle0550${LANG2}.dat subtitle0550 smd 499 | put_strings subtitle/subtitle0552${LANG2}.dat subtitle0552 smd 500 | put_strings subtitle/subtitle0570${LANG2}.dat subtitle0570 smd 501 | put_strings subtitle/subtitle0571${LANG2}.dat subtitle0571 smd 502 | put_strings subtitle/subtitle0590${LANG2}.dat subtitle0590 smd 503 | put_strings subtitle/subtitle0600${LANG2}.dat subtitle0600 smd 504 | put_strings subtitle/subtitle0610${LANG2}.dat subtitle0610 smd 505 | put_strings subtitle/subtitle0612${LANG2}.dat subtitle0612 smd 506 | put_strings subtitle/subtitle0630${LANG2}.dat subtitle0630 smd 507 | put_strings subtitle/subtitle0631${LANG2}.dat subtitle0631 smd 508 | put_strings subtitle/subtitle0640${LANG2}.dat subtitle0640 smd 509 | put_strings subtitle/subtitle0642${LANG2}.dat subtitle0642 smd 510 | put_strings subtitle/subtitle0650${LANG2}.dat subtitle0650 smd 511 | put_strings subtitle/subtitle0651${LANG2}.dat subtitle0651 smd 512 | put_strings subtitle/subtitle0655${LANG2}.dat subtitle0655 smd 513 | put_strings subtitle/subtitle0656${LANG2}.dat subtitle0656 smd 514 | put_strings subtitle/subtitle0660${LANG2}.dat subtitle0660 smd 515 | put_strings subtitle/subtitle0661${LANG2}.dat subtitle0661 smd 516 | put_strings subtitle/subtitle0670${LANG2}.dat subtitle0670 smd 517 | put_strings subtitle/subtitle0671${LANG2}.dat subtitle0671 smd 518 | put_strings subtitle/subtitle0680${LANG2}.dat subtitle0680 smd 519 | put_strings subtitle/subtitle0682${LANG2}.dat subtitle0682 smd 520 | put_strings subtitle/subtitle0690${LANG2}.dat subtitle0690 smd 521 | put_strings subtitle/subtitle0692${LANG2}.dat subtitle0692 smd 522 | put_strings subtitle/subtitle0693${LANG2}.dat subtitle0693 smd 523 | put_strings subtitle/subtitle0694${LANG2}.dat subtitle0694 smd 524 | put_strings subtitle/subtitle0700${LANG2}.dat subtitle0700 smd 525 | put_strings subtitle/subtitle0702${LANG2}.dat subtitle0702 smd 526 | put_strings subtitle/subtitle0720${LANG2}.dat subtitle0720 smd 527 | put_strings subtitle/subtitle0722${LANG2}.dat subtitle0722 smd 528 | put_strings subtitle/subtitle0730${LANG2}.dat subtitle0730 smd 529 | put_strings subtitle/subtitle0760${LANG2}.dat subtitle0760 smd 530 | put_strings subtitle/subtitle0761${LANG2}.dat subtitle0761 smd 531 | put_strings subtitle/subtitle0770${LANG2}.dat subtitle0770 smd 532 | put_strings subtitle/subtitle0771${LANG2}.dat subtitle0771 smd 533 | put_strings subtitle/subtitle0780${LANG2}.dat subtitle0780 smd 534 | put_strings subtitle/subtitle0781${LANG2}.dat subtitle0781 smd 535 | put_strings subtitle/subtitle0790${LANG2}.dat subtitle0790 smd 536 | put_strings subtitle/subtitle0791${LANG2}.dat subtitle0791 smd 537 | put_strings subtitle/subtitle0792${LANG2}.dat subtitle0792 smd 538 | put_strings subtitle/subtitle0800${LANG2}.dat subtitle0800 smd 539 | put_strings subtitle/subtitle0810${LANG2}.dat subtitle0810 smd 540 | put_strings subtitle/subtitle0811${LANG2}.dat subtitle0811 smd 541 | put_strings subtitle/subtitle0820${LANG2}.dat subtitle0820 smd 542 | put_strings subtitle/subtitle0830${LANG2}.dat subtitle0830 smd 543 | put_strings subtitle/subtitle0835${LANG2}.dat subtitle0835 smd 544 | put_strings subtitle/subtitle0836${LANG2}.dat subtitle0836 smd 545 | put_strings subtitle/subtitle0850${LANG2}.dat subtitle0850 smd 546 | put_strings subtitle/subtitle0855${LANG2}.dat subtitle0855 smd 547 | put_strings subtitle/subtitle0860${LANG2}.dat subtitle0860 smd 548 | put_strings subtitle/subtitle0861${LANG2}.dat subtitle0861 smd 549 | put_strings subtitle/subtitle0870${LANG2}.dat subtitle0870 smd 550 | put_strings subtitle/subtitle0871${LANG2}.dat subtitle0871 smd 551 | put_strings subtitle/subtitle0875${LANG2}.dat subtitle0875 smd 552 | put_strings subtitle/subtitle0880${LANG2}.dat subtitle0880 smd 553 | put_strings subtitle/subtitle0900${LANG2}.dat subtitle0900 smd 554 | put_strings subtitle/subtitle0901${LANG2}.dat subtitle0901 smd 555 | put_strings subtitle/subtitle0910${LANG2}.dat subtitle0910 smd 556 | put_strings subtitle/subtitle0920${LANG2}.dat subtitle0920 smd 557 | put_strings subtitle/subtitle0921${LANG2}.dat subtitle0921 smd 558 | put_strings subtitle/subtitle0926${LANG2}.dat subtitle0926 smd 559 | put_strings subtitle/subtitle0930${LANG2}.dat subtitle0930 smd 560 | put_strings subtitle/subtitle0931${LANG2}.dat subtitle0931 smd 561 | put_strings subtitle/subtitle0935${LANG2}.dat subtitle0935 smd 562 | put_strings subtitle/subtitle0936${LANG2}.dat subtitle0936 smd 563 | put_strings subtitle/subtitle0940${LANG2}.dat subtitle0940 smd 564 | put_strings subtitle/subtitle0950${LANG2}.dat subtitle0950 smd 565 | put_strings subtitle/subtitle0951${LANG2}.dat subtitle0951 smd 566 | put_strings subtitle/subtitle0960${LANG2}.dat subtitle0960 smd 567 | put_strings subtitle/subtitle0961${LANG2}.dat subtitle0961 smd 568 | put_strings subtitle/subtitle0970${LANG2}.dat subtitle0970 smd 569 | put_strings subtitle/subtitle0990${LANG2}.dat subtitle0990 smd 570 | put_strings subtitle/subtitle1000${LANG2}.dat subtitle1000 smd 571 | put_strings subtitle/subtitle1001${LANG2}.dat subtitle1001 smd 572 | put_strings subtitle/subtitle1010${LANG2}.dat subtitle1010 smd 573 | put_strings subtitle/subtitle1030${LANG2}.dat subtitle1030 smd 574 | put_strings subtitle/subtitle1040${LANG2}.dat subtitle1040 smd 575 | put_strings subtitle/subtitle1041${LANG2}.dat subtitle1041 smd 576 | put_strings subtitle/subtitle1050${LANG2}.dat subtitle1050 smd 577 | put_strings subtitle/subtitle1051${LANG2}.dat subtitle1051 smd 578 | put_strings subtitle/subtitle1060${LANG2}.dat subtitle1060 smd 579 | put_strings subtitle/subtitle1080${LANG2}.dat subtitle1080 smd 580 | put_strings subtitle/subtitle1090${LANG2}.dat subtitle1090 smd 581 | put_strings subtitle/subtitle1091${LANG2}.dat subtitle1091 smd 582 | put_strings subtitle/subtitle1100${LANG2}.dat subtitle1100 smd 583 | put_strings subtitle/subtitle1120${LANG2}.dat subtitle1120 smd 584 | put_strings subtitle/subtitle1121${LANG2}.dat subtitle1121 smd 585 | put_strings subtitle/subtitle1125${LANG2}.dat subtitle1125 smd 586 | put_strings subtitle/subtitle1150${LANG2}.dat subtitle1150 smd 587 | put_strings subtitle/subtitle1160${LANG2}.dat subtitle1160 smd 588 | put_strings subtitle/subtitle1180${LANG2}.dat subtitle1180 smd 589 | put_strings subtitle/subtitle1181${LANG2}.dat subtitle1181 smd 590 | put_strings subtitle/subtitle1190${LANG2}.dat subtitle1190 smd 591 | put_strings subtitle/subtitle1191${LANG2}.dat subtitle1191 smd 592 | put_strings subtitle/subtitle1210${LANG2}.dat subtitle1210 smd 593 | put_strings subtitle/subtitle1211${LANG2}.dat subtitle1211 smd 594 | put_strings subtitle/subtitle1220${LANG2}.dat subtitle1220 smd 595 | put_strings subtitle/subtitle1221${LANG2}.dat subtitle1221 smd 596 | put_strings subtitle/subtitle1230${LANG2}.dat subtitle1230 smd 597 | put_strings subtitle/subtitle1232${LANG2}.dat subtitle1232 smd 598 | put_strings subtitle/subtitle1233${LANG2}.dat subtitle1233 smd 599 | put_strings subtitle/subtitle1234${LANG2}.dat subtitle1234 smd 600 | put_strings subtitle/subtitle1235${LANG2}.dat subtitle1235 smd 601 | put_strings subtitle/subtitle1240${LANG2}.dat subtitle1240 smd 602 | put_strings subtitle/subtitle1241${LANG2}.dat subtitle1241 smd 603 | put_strings subtitle/subtitle1250${LANG2}.dat subtitle1250 smd 604 | put_strings subtitle/subtitle1260${LANG2}.dat subtitle1260 smd 605 | put_strings subtitle/subtitle1270${LANG2}.dat subtitle1270 smd 606 | put_strings subtitle/subtitle1280${LANG2}.dat subtitle1280 smd 607 | put_strings subtitle/subtitle1290${LANG2}.dat subtitle1290 smd 608 | put_strings subtitle/subtitle1300${LANG2}.dat subtitle1300 smd 609 | put_strings subtitle/subtitle1310${LANG2}.dat subtitle1310 smd 610 | put_strings subtitle/subtitle1320${LANG2}.dat subtitle1320 smd 611 | put_strings subtitle/subtitle1400${LANG2}.dat subtitle1400 smd 612 | put_strings subtitle/subtitle1402${LANG2}.dat subtitle1402 smd 613 | put_strings subtitle/subtitleb060${LANG2}.dat subtitleb060 smd 614 | put_strings subtitle/subtitleb191${LANG2}.dat subtitleb191 smd 615 | put_strings subtitle/subtitleb251${LANG2}.dat subtitleb251 smd 616 | put_strings subtitle/subtitleb301${LANG2}.dat subtitleb301 smd 617 | put_strings subtitle/subtitleb311${LANG2}.dat subtitleb311 smd 618 | put_strings subtitle/subtitleb321${LANG2}.dat subtitleb321 smd 619 | put_strings subtitle/subtitleb341${LANG2}.dat subtitleb341 smd 620 | put_strings subtitle/subtitleb351${LANG2}.dat subtitleb351 smd 621 | put_strings subtitle/subtitleb441${LANG2}.dat subtitleb441 smd 622 | put_strings subtitle/subtitleb461${LANG2}.dat subtitleb461 smd 623 | put_strings subtitle/subtitleb471${LANG2}.dat subtitleb471 smd 624 | put_strings subtitle/subtitleb651${LANG2}.dat subtitleb651 smd 625 | put_strings subtitle/subtitleb656${LANG2}.dat subtitleb656 smd 626 | put_strings subtitle/subtitleb661${LANG2}.dat subtitleb661 smd 627 | put_strings subtitle/subtitleb671${LANG2}.dat subtitleb671 smd 628 | put_strings txtmess/txt_chapter${LANG2}.dat txt_chapter tmd 629 | put_strings txtmess/txt_core_add${LANG2}.dat txt_core_add tmd 630 | put_strings txtmess/txt_core${LANG2}.dat txt_core tmd 631 | put_strings txtmess/txt_credit${LANG2}.dat txt_credit tmd 632 | put_strings txtmess/txt_dlc1${LANG2}.dat txt_dlc1 tmd 633 | put_strings txtmess/txt_dlc2${LANG2}.dat txt_dlc2 tmd 634 | put_strings txtmess/txt_dlc3${LANG2}.dat txt_dlc3 tmd 635 | put_strings txtmess/txt_hud_add${LANG2}.dat txt_hud_add tmd 636 | put_strings txtmess/txt_hud${LANG2}.dat txt_hud tmd 637 | put_strings txtmess/txt_pause_add${LANG2}.dat txt_pause_add tmd 638 | put_strings txtmess/txt_pause${LANG2}.dat txt_pause tmd 639 | put_strings txtmess/txt_shop${LANG2}.dat txt_shop tmd 640 | put_strings txtmess/txt_support${LANG2}.dat txt_support tmd 641 | put_strings ui/ui_chapter${LANG2}.dat messchapter mcd 642 | put_strings ui/ui_core_2${LANG2}.dat messcore_2 mcd 643 | put_strings ui/ui_core_pc${LANG2}.dat messcore_pc mcd 644 | put_strings ui/ui_core${LANG2}.dat messcore mcd 645 | put_strings ui/ui_credit${LANG2}.dat messcredit mcd 646 | put_strings ui/ui_dbg${LANG2}.dat messdbg mcd 647 | put_strings ui/ui_dlc1${LANG2}.dat messdlc1 mcd 648 | put_strings ui/ui_dlc2${LANG2}.dat messdlc2 mcd 649 | put_strings ui/ui_dlc3${LANG2}.dat messdlc3 mcd 650 | put_strings ui/ui_ending_dlc${LANG2}.dat messending_dlc mcd 651 | put_strings ui/ui_ending${LANG2}.dat messending mcd 652 | put_strings ui/ui_event${LANG2}.dat messevent mcd 653 | put_strings ui/ui_hud_hacking${LANG2}.dat messhud_hacking mcd 654 | put_strings ui/ui_hud${LANG2}.dat messhud mcd 655 | put_strings ui/ui_loading.dat messloading mcd 656 | put_strings ui/ui_option${LANG2}.dat messoption mcd 657 | put_strings ui/ui_pause${LANG2}.dat messpause mcd 658 | put_strings ui/ui_shop${LANG2}.dat messshop mcd 659 | put_strings ui/ui_title${LANG2}.dat messtitle mcd 660 | put_strings wd1/g11516.dat g11516_2ccba2ea_scp bin; repack_dat wd1/g11516.dat 661 | put_strings novel M1030_S0310_N${LANG3} txt 662 | put_strings novel M1070_S0020_N${LANG3} txt 663 | put_strings novel M1070_S0040_N${LANG3} txt 664 | put_strings novel M1070_S0060_N${LANG3} txt 665 | put_strings novel M1070_S0080_N${LANG3} txt 666 | put_strings novel M1070_S0100_N${LANG3} txt 667 | put_strings novel M3060_S0005_N${LANG3} txt 668 | put_strings novel M3060_S0035_GM_N${LANG3} txt 669 | put_strings novel M3060_S0910_N${LANG3} txt 670 | put_strings novel M6010_S0050_N${LANG3} txt 671 | put_strings novel M6010_S0150_N${LANG3} txt 672 | put_strings novel M6010_S0250_N${LANG3} txt 673 | put_strings novel M9000_S0500_N${LANG3} txt 674 | put_strings novel M5095_S0020_N${LANG3} txt 675 | put_strings novel M5095_S0025_N${LANG3} txt 676 | put_strings novel M5095_S0100_N${LANG3} txt 677 | put_strings novel M5095_S0200_N${LANG3} txt 678 | put_strings novel M5095_S0300_N${LANG3} txt 679 | -------------------------------------------------------------------------------- /data/files_list.txt: -------------------------------------------------------------------------------- 1 | This directory should contain files unpacked from cpk packages: 2 | 3 | data002.cpk: 4 | core\corehap.dat 5 | ph1\p100.dat 6 | phf\pf30.dat 7 | st1\r100.dat 8 | st1\r120.dat 9 | 10 | data009.cpk: 11 | font\font_00.dat 12 | font\font_00.dtt 13 | font\font_01.dat 14 | font\font_01.dtt 15 | font\font_04.dat 16 | font\font_04.dtt 17 | font\font_05.dat 18 | font\font_05.dtt 19 | font\font_11.dat 20 | font\font_11.dtt 21 | subtitle\subtitle0010_us.dat 22 | subtitle\subtitle0011_us.dat 23 | subtitle\subtitle0030_us.dat 24 | subtitle\subtitle0031_us.dat 25 | subtitle\subtitle0040_us.dat 26 | subtitle\subtitle0050_us.dat 27 | subtitle\subtitle0055_us.dat 28 | subtitle\subtitle0060_us.dat 29 | subtitle\subtitle0080_us.dat 30 | subtitle\subtitle0081_us.dat 31 | subtitle\subtitle0086_us.dat 32 | subtitle\subtitle0090_us.dat 33 | subtitle\subtitle0091_us.dat 34 | subtitle\subtitle0092_us.dat 35 | subtitle\subtitle0110_us.dat 36 | subtitle\subtitle0111_us.dat 37 | subtitle\subtitle0120_us.dat 38 | subtitle\subtitle0130_us.dat 39 | subtitle\subtitle0140_us.dat 40 | subtitle\subtitle0160_us.dat 41 | subtitle\subtitle0170_us.dat 42 | subtitle\subtitle0190_us.dat 43 | subtitle\subtitle0191_us.dat 44 | subtitle\subtitle0225_us.dat 45 | subtitle\subtitle0226_us.dat 46 | subtitle\subtitle0230_us.dat 47 | subtitle\subtitle0240_us.dat 48 | subtitle\subtitle0241_us.dat 49 | subtitle\subtitle0250_us.dat 50 | subtitle\subtitle0251_us.dat 51 | subtitle\subtitle0260_us.dat 52 | subtitle\subtitle0262_us.dat 53 | subtitle\subtitle0270_us.dat 54 | subtitle\subtitle0280_us.dat 55 | subtitle\subtitle0300_us.dat 56 | subtitle\subtitle0301_us.dat 57 | subtitle\subtitle0310_us.dat 58 | subtitle\subtitle0311_us.dat 59 | subtitle\subtitle0320_us.dat 60 | subtitle\subtitle0321_us.dat 61 | subtitle\subtitle0322_us.dat 62 | subtitle\subtitle0323_us.dat 63 | subtitle\subtitle0325_us.dat 64 | subtitle\subtitle0326_us.dat 65 | subtitle\subtitle0330_us.dat 66 | subtitle\subtitle0340_us.dat 67 | subtitle\subtitle0341_us.dat 68 | subtitle\subtitle0350_us.dat 69 | subtitle\subtitle0351_us.dat 70 | subtitle\subtitle0352_us.dat 71 | subtitle\subtitle0360_us.dat 72 | subtitle\subtitle0370_us.dat 73 | subtitle\subtitle0390_us.dat 74 | subtitle\subtitle0400_us.dat 75 | subtitle\subtitle0410_us.dat 76 | subtitle\subtitle0420_us.dat 77 | subtitle\subtitle0440_us.dat 78 | subtitle\subtitle0441_us.dat 79 | subtitle\subtitle0460_us.dat 80 | subtitle\subtitle0461_us.dat 81 | subtitle\subtitle0470_us.dat 82 | subtitle\subtitle0471_us.dat 83 | subtitle\subtitle0475_us.dat 84 | subtitle\subtitle0480_us.dat 85 | subtitle\subtitle0482_us.dat 86 | subtitle\subtitle0483_us.dat 87 | subtitle\subtitle0485_us.dat 88 | subtitle\subtitle0490_us.dat 89 | subtitle\subtitle0491_us.dat 90 | subtitle\subtitle0500_us.dat 91 | subtitle\subtitle0502_us.dat 92 | subtitle\subtitle0520_us.dat 93 | subtitle\subtitle0521_us.dat 94 | subtitle\subtitle0525_us.dat 95 | subtitle\subtitle0526_us.dat 96 | subtitle\subtitle0530_us.dat 97 | subtitle\subtitle0531_us.dat 98 | subtitle\subtitle0540_us.dat 99 | subtitle\subtitle0550_us.dat 100 | subtitle\subtitle0552_us.dat 101 | subtitle\subtitle0570_us.dat 102 | subtitle\subtitle0571_us.dat 103 | subtitle\subtitle0590_us.dat 104 | subtitle\subtitle0600_us.dat 105 | subtitle\subtitle0610_us.dat 106 | subtitle\subtitle0612_us.dat 107 | subtitle\subtitle0630_us.dat 108 | subtitle\subtitle0631_us.dat 109 | subtitle\subtitle0640_us.dat 110 | subtitle\subtitle0642_us.dat 111 | subtitle\subtitle0650_us.dat 112 | subtitle\subtitle0651_us.dat 113 | subtitle\subtitle0655_us.dat 114 | subtitle\subtitle0656_us.dat 115 | subtitle\subtitle0660_us.dat 116 | subtitle\subtitle0661_us.dat 117 | subtitle\subtitle0670_us.dat 118 | subtitle\subtitle0671_us.dat 119 | subtitle\subtitle0680_us.dat 120 | subtitle\subtitle0682_us.dat 121 | subtitle\subtitle0690_us.dat 122 | subtitle\subtitle0692_us.dat 123 | subtitle\subtitle0693_us.dat 124 | subtitle\subtitle0694_us.dat 125 | subtitle\subtitle0700_us.dat 126 | subtitle\subtitle0702_us.dat 127 | subtitle\subtitle0720_us.dat 128 | subtitle\subtitle0722_us.dat 129 | subtitle\subtitle0730_us.dat 130 | subtitle\subtitle0760_us.dat 131 | subtitle\subtitle0761_us.dat 132 | subtitle\subtitle0770_us.dat 133 | subtitle\subtitle0771_us.dat 134 | subtitle\subtitle0780_us.dat 135 | subtitle\subtitle0781_us.dat 136 | subtitle\subtitle0790_us.dat 137 | subtitle\subtitle0791_us.dat 138 | subtitle\subtitle0792_us.dat 139 | subtitle\subtitle0800_us.dat 140 | subtitle\subtitle0810_us.dat 141 | subtitle\subtitle0811_us.dat 142 | subtitle\subtitle0820_us.dat 143 | subtitle\subtitle0830_us.dat 144 | subtitle\subtitle0835_us.dat 145 | subtitle\subtitle0836_us.dat 146 | subtitle\subtitle0850_us.dat 147 | subtitle\subtitle0855_us.dat 148 | subtitle\subtitle0860_us.dat 149 | subtitle\subtitle0861_us.dat 150 | subtitle\subtitle0870_us.dat 151 | subtitle\subtitle0871_us.dat 152 | subtitle\subtitle0875_us.dat 153 | subtitle\subtitle0880_us.dat 154 | subtitle\subtitle0900_us.dat 155 | subtitle\subtitle0901_us.dat 156 | subtitle\subtitle0910_us.dat 157 | subtitle\subtitle0920_us.dat 158 | subtitle\subtitle0921_us.dat 159 | subtitle\subtitle0926_us.dat 160 | subtitle\subtitle0930_us.dat 161 | subtitle\subtitle0931_us.dat 162 | subtitle\subtitle0935_us.dat 163 | subtitle\subtitle0936_us.dat 164 | subtitle\subtitle0940_us.dat 165 | subtitle\subtitle0950_us.dat 166 | subtitle\subtitle0951_us.dat 167 | subtitle\subtitle0960_us.dat 168 | subtitle\subtitle0961_us.dat 169 | subtitle\subtitle0970_us.dat 170 | subtitle\subtitle0990_us.dat 171 | subtitle\subtitle1000_us.dat 172 | subtitle\subtitle1001_us.dat 173 | subtitle\subtitle1010_us.dat 174 | subtitle\subtitle1030_us.dat 175 | subtitle\subtitle1040_us.dat 176 | subtitle\subtitle1041_us.dat 177 | subtitle\subtitle1050_us.dat 178 | subtitle\subtitle1051_us.dat 179 | subtitle\subtitle1060_us.dat 180 | subtitle\subtitle1080_us.dat 181 | subtitle\subtitle1090_us.dat 182 | subtitle\subtitle1091_us.dat 183 | subtitle\subtitle1100_us.dat 184 | subtitle\subtitle1120_us.dat 185 | subtitle\subtitle1121_us.dat 186 | subtitle\subtitle1125_us.dat 187 | subtitle\subtitle1150_us.dat 188 | subtitle\subtitle1160_us.dat 189 | subtitle\subtitle1180_us.dat 190 | subtitle\subtitle1181_us.dat 191 | subtitle\subtitle1190_us.dat 192 | subtitle\subtitle1191_us.dat 193 | subtitle\subtitle1210_us.dat 194 | subtitle\subtitle1211_us.dat 195 | subtitle\subtitle1220_us.dat 196 | subtitle\subtitle1221_us.dat 197 | subtitle\subtitle1230_us.dat 198 | subtitle\subtitle1232_us.dat 199 | subtitle\subtitle1233_us.dat 200 | subtitle\subtitle1234_us.dat 201 | subtitle\subtitle1235_us.dat 202 | subtitle\subtitle1240_us.dat 203 | subtitle\subtitle1241_us.dat 204 | subtitle\subtitle1250_us.dat 205 | subtitle\subtitle1260_us.dat 206 | subtitle\subtitle1270_us.dat 207 | subtitle\subtitle1280_us.dat 208 | subtitle\subtitle1400_us.dat 209 | subtitle\subtitle1402_us.dat 210 | subtitle\subtitleb060_us.dat 211 | subtitle\subtitleb191_us.dat 212 | subtitle\subtitleb251_us.dat 213 | subtitle\subtitleb301_us.dat 214 | subtitle\subtitleb311_us.dat 215 | subtitle\subtitleb321_us.dat 216 | subtitle\subtitleb341_us.dat 217 | subtitle\subtitleb351_us.dat 218 | subtitle\subtitleb441_us.dat 219 | subtitle\subtitleb461_us.dat 220 | subtitle\subtitleb471_us.dat 221 | subtitle\subtitleb651_us.dat 222 | subtitle\subtitleb656_us.dat 223 | subtitle\subtitleb661_us.dat 224 | subtitle\subtitleb671_us.dat 225 | novel\M9000_S0500_N_eng.txt 226 | txtmess\txt_chapter_us.dat 227 | txtmess\txt_core_add_us.dat 228 | txtmess\txt_core_us.dat 229 | txtmess\txt_credit_us.dat 230 | txtmess\txt_hud_add_us.dat 231 | txtmess\txt_hud_us.dat 232 | txtmess\txt_pause_add_us.dat 233 | txtmess\txt_pause_us.dat 234 | txtmess\txt_shop_us.dat 235 | txtmess\txt_support_us.dat 236 | ui\ui_chapter_us.dat 237 | ui\ui_chapter_us.dtt 238 | ui\ui_core_2_us.dat 239 | ui\ui_core_2_us.dtt 240 | ui\ui_core_pc_us.dat 241 | ui\ui_core_pc_us.dtt 242 | ui\ui_core_us.dat 243 | ui\ui_core_us.dtt 244 | ui\ui_credit_us.dat 245 | ui\ui_credit_us.dtt 246 | ui\ui_dbg_us.dat 247 | ui\ui_dbg_us.dtt 248 | ui\ui_ending_us.dat 249 | ui\ui_ending_us.dtt 250 | ui\ui_event_us.dat 251 | ui\ui_event_us.dtt 252 | ui\ui_hud_hacking_us.dat 253 | ui\ui_hud_hacking_us.dtt 254 | ui\ui_hud_us.dat 255 | ui\ui_hud_us.dtt 256 | ui\ui_option_us.dat 257 | ui\ui_option_us.dtt 258 | ui\ui_pause_us.dat 259 | ui\ui_pause_us.dtt 260 | ui\ui_shop_us.dat 261 | ui\ui_shop_us.dtt 262 | ui\ui_title_us.dat 263 | ui\ui_title_us.dtt 264 | 265 | data012.cpk: 266 | ph2\p200.dat 267 | ph3\p300.dat 268 | phf\pf10.dat 269 | phf\pf31.dat 270 | st1\r110.dat 271 | st1\r130.dat 272 | st1\r140.dat 273 | st1\r150.dat 274 | st1\r160.dat 275 | st1\r170.dat 276 | st2\r200.dat 277 | st5\r530.dat 278 | quest\q020.dat 279 | quest\q031.dat 280 | quest\q032.dat 281 | quest\q040.dat 282 | quest\q070.dat 283 | quest\q071.dat 284 | quest\q100.dat 285 | quest\q101.dat 286 | quest\q102.dat 287 | quest\q103.dat 288 | quest\q104.dat 289 | quest\q110.dat 290 | quest\q120.dat 291 | quest\q121.dat 292 | quest\q122.dat 293 | quest\q123.dat 294 | quest\q130.dat 295 | quest\q140.dat 296 | quest\q150.dat 297 | quest\q160.dat 298 | quest\q162.dat 299 | quest\q170.dat 300 | quest\q171.dat 301 | quest\q180.dat 302 | quest\q181.dat 303 | quest\q210.dat 304 | quest\q220.dat 305 | quest\q221.dat 306 | quest\q222.dat 307 | quest\q290.dat 308 | quest\q300.dat 309 | quest\q330.dat 310 | quest\q340.dat 311 | quest\q360.dat 312 | quest\q400.dat 313 | quest\q401.dat 314 | quest\q403.dat 315 | quest\q410.dat 316 | quest\q440.dat 317 | quest\q500.dat 318 | quest\q520.dat 319 | quest\q532.dat 320 | quest\q540.dat 321 | quest\q550.dat 322 | quest\q560.dat 323 | quest\q561.dat 324 | quest\q562.dat 325 | quest\q590.dat 326 | quest\q640.dat 327 | quest\q650.dat 328 | quest\q651.dat 329 | quest\q652.dat 330 | quest\q660.dat 331 | quest\q680.dat 332 | quest\q720.dat 333 | quest\q770.dat 334 | quest\q800.dat 335 | quest\q801.dat 336 | quest\q900.dat 337 | quest\q910.dat 338 | quest\q920.dat 339 | quest\qab2.dat 340 | quest\qab3.dat 341 | quest\qab5.dat 342 | quest\qab6.dat 343 | quest\qaba.dat 344 | quest\qabb.dat 345 | quest\qabd.dat 346 | quest\qac8.dat 347 | quest\qad0.dat 348 | quest\qad1.dat 349 | quest\qad2.dat 350 | quest\qad6.dat 351 | quest\qaeb.dat 352 | quest\qaef.dat 353 | quest\qaf4.dat 354 | quest\qb20.dat 355 | quest\qb40.dat 356 | quest\qc10.dat 357 | quest\qc11.dat 358 | quest\qc12.dat 359 | quest\qc30.dat 360 | 361 | data013.cpk: 362 | wd1\g11516.dat 363 | 364 | data019.cpk: 365 | novel\M1030_S0310_N_eng.txt 366 | novel\M1070_S0020_N_eng.txt 367 | novel\M1070_S0040_N_eng.txt 368 | novel\M1070_S0060_N_eng.txt 369 | novel\M1070_S0080_N_eng.txt 370 | novel\M1070_S0100_N_eng.txt 371 | novel\M3060_S0005_N_eng.txt 372 | novel\M3060_S0035_GM_N_eng.txt 373 | novel\M3060_S0035_GM_N_Sample_0912_eng.txt 374 | novel\M3060_S0910_N_eng.txt 375 | novel\M6010_S0050_N_eng.txt 376 | novel\M6010_S0150_N_eng.txt 377 | novel\M6010_S0250_N_eng.txt 378 | 379 | data100.cpk: 380 | ph4\p400.dat 381 | phf\pf60.dat 382 | quest\q080.dat 383 | quest\q090.dat 384 | quest\q091.dat 385 | quest\q092.dat 386 | quest\q095.dat 387 | quest\qc50.dat 388 | novel\M5095_S0020_N_eng.txt 389 | novel\M5095_S0025_N_eng.txt 390 | novel\M5095_S0100_N_eng.txt 391 | novel\M5095_S0200_N_eng.txt 392 | novel\M5095_S0300_N_eng.txt 393 | subtitle\subtitle1290_us.dat 394 | subtitle\subtitle1300_us.dat 395 | subtitle\subtitle1310_us.dat 396 | subtitle\subtitle1320_us.dat 397 | txtmess\txt_dlc1_us.dat 398 | txtmess\txt_dlc2_us.dat 399 | txtmess\txt_dlc3_us.dat 400 | ui\ui_dlc1_us.dat 401 | ui\ui_dlc1_us.dtt 402 | ui\ui_dlc2_us.dat 403 | ui\ui_dlc2_us.dtt 404 | ui\ui_dlc3_us.dat 405 | ui\ui_dlc3_us.dtt 406 | ui\ui_ending_dlc_us.dat 407 | ui\ui_ending_dlc_us.dtt 408 | ui\ui_loading.dat 409 | ui\ui_loading.dtt 410 | 411 | -------------------------------------------------------------------------------- /fonts/fonts.json: -------------------------------------------------------------------------------- 1 | { 2 | "00" : { "glyphs": "fonts/00", "kerning": null , "below" : -6.0 }, 3 | "02" : { "glyphs": "fonts/02", "kerning": null , "below" : -10.0 }, 4 | "03" : { "glyphs": "fonts/03", "kerning": null , "below" : 0.0 }, 5 | "08" : { "glyphs": "fonts/08", "kerning": null , "below" : 1.0 }, 6 | "09" : { "glyphs": "fonts/09", "kerning": null , "below" : -7.0 }, 7 | "10" : { "glyphs": "fonts/10", "kerning": null , "below" : -3.0 }, 8 | "01" : { "glyphs": "fonts/01", "kerning": "assembly/font/font_01.dat/font_01.ktb" , "below" : -5.0 }, 9 | "06" : { "glyphs": "fonts/01", "kerning": "assembly/font/font_01.dat/font_01.ktb" , "below" : -5.0 }, 10 | "36" : { "glyphs": "fonts/01", "kerning": "assembly/font/font_01.dat/font_01.ktb" , "below" : -7.0 }, 11 | "37" : { "glyphs": "fonts/01", "kerning": "assembly/font/font_01.dat/font_01.ktb" , "below" : -7.0 }, 12 | "04" : { "glyphs": "fonts/04", "kerning": "assembly/font/font_04.dat/font_04.ktb" , "below" : -5.0 }, 13 | "05" : { "glyphs": "fonts/05", "kerning": "assembly/font/font_05.dat/font_05.ktb" , "below" : -10.0 }, 14 | "07" : { "glyphs": "fonts/05", "kerning": "assembly/font/font_05.dat/font_05.ktb" , "below" : -10.0 }, 15 | "35" : { "glyphs": "fonts/05", "kerning": "assembly/font/font_05.dat/font_05.ktb" , "below" : -11.0 }, 16 | "11" : { "glyphs": "fonts/11", "kerning": "assembly/font/font_11.dat/font_11.ktb" , "below" : -7.0 } 17 | } 18 | -------------------------------------------------------------------------------- /get_strings.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function get_strings() { 4 | raw=$1 5 | properties=$2 6 | echo "Extracting ${raw}" 7 | if [ "${raw##*.}" == "txt" ] 8 | then 9 | cp unpacked/${raw} source/${properties} 10 | else 11 | ./tools/get_strings.py --lang en unpacked/${raw} source/${properties} 12 | fi 13 | #./tools/get_strings.py --lang en --keep-non-ascii unpacked/${raw} jp/${properties} 14 | } 15 | 16 | mkdir -p source 17 | #empty LANG2 and LANG3 are for jp 18 | LANG2="_us" # _fr _it _de _es 19 | LANG3="_eng" # _fra _ita _ger _esp 20 | 21 | get_strings core/corehap.dat/core_hap.pak core_hap.properties 22 | get_strings ui/ui_loading.dat/messloading.mcd messloading.properties 23 | get_strings ui/ui_title${LANG2}.dat/messtitle.mcd messtitle.properties 24 | get_strings ui/ui_option${LANG2}.dat/messoption.mcd messoption.properties 25 | get_strings ui/ui_core_pc${LANG2}.dat/messcore_pc.mcd messcore_pc.properties 26 | get_strings ui/ui_core${LANG2}.dat/messcore.mcd messcore.properties 27 | get_strings ui/ui_core_2${LANG2}.dat/messcore_2.mcd messcore_2.properties 28 | get_strings txtmess/txt_core${LANG2}.dat/txt_core.tmd txt_core.properties 29 | get_strings txtmess/txt_core_add${LANG2}.dat/txt_core_add.tmd txt_core_add.properties 30 | get_strings ui/ui_pause${LANG2}.dat/messpause.mcd messpause.properties 31 | get_strings txtmess/txt_pause${LANG2}.dat/txt_pause.tmd txt_pause.properties 32 | get_strings txtmess/txt_pause_add${LANG2}.dat/txt_pause_add.tmd txt_pause_add.properties 33 | get_strings ui/ui_shop${LANG2}.dat/messshop.mcd messshop.properties 34 | get_strings txtmess/txt_shop${LANG2}.dat/txt_shop.tmd txt_shop.properties 35 | get_strings ui/ui_hud${LANG2}.dat/messhud.mcd messhud.properties 36 | get_strings ui/ui_hud_hacking${LANG2}.dat/messhud_hacking.mcd messhud_hacking.properties 37 | get_strings txtmess/txt_hud${LANG2}.dat/txt_hud.tmd txt_hud.properties 38 | get_strings txtmess/txt_hud_add${LANG2}.dat/txt_hud_add.tmd txt_hud_add.properties 39 | get_strings ui/ui_event${LANG2}.dat/messevent.mcd messevent.properties 40 | get_strings ui/ui_credit${LANG2}.dat/messcredit.mcd messcredit.properties 41 | get_strings txtmess/txt_credit${LANG2}.dat/txt_credit.tmd txt_credit.properties 42 | get_strings ui/ui_dbg${LANG2}.dat/messdbg.mcd messdbg.properties 43 | get_strings ui/ui_chapter${LANG2}.dat/messchapter.mcd messchapter.properties 44 | get_strings txtmess/txt_chapter${LANG2}.dat/txt_chapter.tmd txt_chapter.properties 45 | get_strings ui/ui_ending${LANG2}.dat/messending.mcd messending.properties 46 | get_strings txtmess/txt_support${LANG2}.dat/txt_support.tmd txt_support.properties 47 | get_strings ui/ui_dlc1${LANG2}.dat/messdlc1.mcd messdlc1.properties 48 | get_strings ui/ui_dlc2${LANG2}.dat/messdlc2.mcd messdlc2.properties 49 | get_strings ui/ui_dlc3${LANG2}.dat/messdlc3.mcd messdlc3.properties 50 | get_strings txtmess/txt_dlc1${LANG2}.dat/txt_dlc1.tmd txt_dlc1.properties 51 | get_strings txtmess/txt_dlc2${LANG2}.dat/txt_dlc2.tmd txt_dlc2.properties 52 | get_strings txtmess/txt_dlc3${LANG2}.dat/txt_dlc3.tmd txt_dlc3.properties 53 | get_strings ui/ui_ending_dlc${LANG2}.dat/messending_dlc.mcd messending_dlc.properties 54 | get_strings ph1/p100.dat/p100_fa238e7c_scp.bin p100_fa238e7c_scp.properties 55 | get_strings ph1/p100.dat/p100_c6ab1d8f_scp.bin p100_c6ab1d8f_scp.properties 56 | get_strings subtitle/subtitle0010${LANG2}.dat/subtitle0010.smd subtitle0010.properties 57 | get_strings subtitle/subtitle0011${LANG2}.dat/subtitle0011.smd subtitle0011.properties 58 | get_strings subtitle/subtitle0030${LANG2}.dat/subtitle0030.smd subtitle0030.properties 59 | get_strings subtitle/subtitle0031${LANG2}.dat/subtitle0031.smd subtitle0031.properties 60 | get_strings ph1/p100.dat/p100_dfcc155d_scp.bin p100_dfcc155d_scp.properties 61 | get_strings ph1/p100.dat/p100_7f31f924_scp.bin p100_7f31f924_scp.properties 62 | get_strings subtitle/subtitle0040${LANG2}.dat/subtitle0040.smd subtitle0040.properties 63 | get_strings ph1/p100.dat/p100_d8a4a747_scp.bin p100_d8a4a747_scp.properties 64 | get_strings ph1/p100.dat/p100_e1dc4db4_scp.bin p100_e1dc4db4_scp.properties 65 | get_strings ph1/p100.dat/p100_e2d39d13_scp.bin p100_e2d39d13_scp.properties 66 | get_strings subtitle/subtitle0055${LANG2}.dat/subtitle0055.smd subtitle0055.properties 67 | get_strings subtitle/subtitle0060${LANG2}.dat/subtitle0060.smd subtitle0060.properties 68 | get_strings subtitle/subtitleb060${LANG2}.dat/subtitleb060.smd subtitleb060.properties 69 | get_strings ph1/p100.dat/p100_440fda42_scp.bin p100_440fda42_scp.properties 70 | get_strings ph1/p100.dat/p100_536bd4fb_scp.bin p100_536bd4fb_scp.properties 71 | get_strings ph1/p100.dat/p100_7c282dc8_scp.bin p100_7c282dc8_scp.properties 72 | get_strings st1/r120.dat/r120_f0d26b5d_scp.bin r120_f0d26b5d_scp.properties 73 | get_strings ph1/p100.dat/p100_cbfd7706_scp.bin p100_cbfd7706_scp.properties 74 | get_strings ph1/p100.dat/p100_6a34d49e_scp.bin p100_6a34d49e_scp.properties 75 | get_strings ph1/p100.dat/p100_301b50d3_scp.bin p100_301b50d3_scp.properties 76 | get_strings ph1/p100.dat/p100_5f2b7c58_scp.bin p100_5f2b7c58_scp.properties 77 | get_strings ph1/p100.dat/p100_a85f65ec_scp.bin p100_a85f65ec_scp.properties 78 | get_strings subtitle/subtitle0080${LANG2}.dat/subtitle0080.smd subtitle0080.properties 79 | get_strings subtitle/subtitle0081${LANG2}.dat/subtitle0081.smd subtitle0081.properties 80 | get_strings ph1/p100.dat/p100_10a1b8c_scp.bin p100_10a1b8c_scp.properties 81 | get_strings subtitle/subtitle0086${LANG2}.dat/subtitle0086.smd subtitle0086.properties 82 | get_strings ph1/p100.dat/p100_8371cfcf_scp.bin p100_8371cfcf_scp.properties 83 | get_strings subtitle/subtitle0090${LANG2}.dat/subtitle0090.smd subtitle0090.properties 84 | get_strings subtitle/subtitle0091${LANG2}.dat/subtitle0091.smd subtitle0091.properties 85 | get_strings subtitle/subtitle0092${LANG2}.dat/subtitle0092.smd subtitle0092.properties 86 | get_strings ph1/p100.dat/p100_54edd5c_scp.bin p100_54edd5c_scp.properties 87 | get_strings subtitle/subtitle0110${LANG2}.dat/subtitle0110.smd subtitle0110.properties 88 | get_strings subtitle/subtitle0111${LANG2}.dat/subtitle0111.smd subtitle0111.properties 89 | get_strings quest/qac8.dat/qac8_fd8ac7ea_scp.bin qac8_fd8ac7ea_scp.properties 90 | get_strings quest/qaf4.dat/qaf4_e04e13b1_scp.bin qaf4_e04e13b1_scp.properties 91 | get_strings subtitle/subtitle0120${LANG2}.dat/subtitle0120.smd subtitle0120.properties 92 | get_strings ph1/p100.dat/p100_ce928ad9_scp.bin p100_ce928ad9_scp.properties 93 | get_strings ph1/p100.dat/p100_89910ddf_scp.bin p100_89910ddf_scp.properties 94 | get_strings subtitle/subtitle0130${LANG2}.dat/subtitle0130.smd subtitle0130.properties 95 | get_strings ph1/p100.dat/p100_a5817204_scp.bin p100_a5817204_scp.properties 96 | get_strings subtitle/subtitle0140${LANG2}.dat/subtitle0140.smd subtitle0140.properties 97 | get_strings ph1/p100.dat/p100_6695192d_scp.bin p100_6695192d_scp.properties 98 | get_strings subtitle/subtitle0160${LANG2}.dat/subtitle0160.smd subtitle0160.properties 99 | get_strings subtitle/subtitle0050${LANG2}.dat/subtitle0050.smd subtitle0050.properties 100 | get_strings subtitle/subtitle0170${LANG2}.dat/subtitle0170.smd subtitle0170.properties 101 | get_strings ph1/p100.dat/p100_4aa7dace_scp.bin p100_4aa7dace_scp.properties 102 | get_strings ph1/p100.dat/p100_43f203b8_scp.bin p100_43f203b8_scp.properties 103 | get_strings ph1/p100.dat/p100_90998b13_scp.bin p100_90998b13_scp.properties 104 | get_strings subtitle/subtitle0190${LANG2}.dat/subtitle0190.smd subtitle0190.properties 105 | get_strings subtitle/subtitle0191${LANG2}.dat/subtitle0191.smd subtitle0191.properties 106 | get_strings subtitle/subtitleb191${LANG2}.dat/subtitleb191.smd subtitleb191.properties 107 | get_strings ph1/p100.dat/p100_973474b4_scp.bin p100_973474b4_scp.properties 108 | get_strings ph1/p100.dat/p100_69ab2de6_scp.bin p100_69ab2de6_scp.properties 109 | get_strings ph1/p100.dat/p100_643b9449_scp.bin p100_643b9449_scp.properties 110 | get_strings ph1/p100.dat/p100_306867fd_scp.bin p100_306867fd_scp.properties 111 | get_strings ph1/p100.dat/p100_61b598fd_scp.bin p100_61b598fd_scp.properties 112 | get_strings st1/r150.dat/r150_5ced6cf8_scp.bin r150_5ced6cf8_scp.properties 113 | get_strings subtitle/subtitle0225${LANG2}.dat/subtitle0225.smd subtitle0225.properties 114 | get_strings subtitle/subtitle0226${LANG2}.dat/subtitle0226.smd subtitle0226.properties 115 | get_strings ph1/p100.dat/p100_39cda07a_scp.bin p100_39cda07a_scp.properties 116 | get_strings ph1/p100.dat/p100_9092a1f1_scp.bin p100_9092a1f1_scp.properties 117 | get_strings subtitle/subtitle0240${LANG2}.dat/subtitle0240.smd subtitle0240.properties 118 | get_strings subtitle/subtitle0241${LANG2}.dat/subtitle0241.smd subtitle0241.properties 119 | get_strings subtitle/subtitle0230${LANG2}.dat/subtitle0230.smd subtitle0230.properties 120 | get_strings ph1/p100.dat/p100_1a401b0f_scp.bin p100_1a401b0f_scp.properties 121 | get_strings ph1/p100.dat/p100_ec82f9bf_scp.bin p100_ec82f9bf_scp.properties 122 | get_strings subtitle/subtitle0250${LANG2}.dat/subtitle0250.smd subtitle0250.properties 123 | get_strings subtitle/subtitle0251${LANG2}.dat/subtitle0251.smd subtitle0251.properties 124 | get_strings subtitle/subtitleb251${LANG2}.dat/subtitleb251.smd subtitleb251.properties 125 | get_strings ph1/p100.dat/p100_cb2621f3_scp.bin p100_cb2621f3_scp.properties 126 | get_strings subtitle/subtitle0260${LANG2}.dat/subtitle0260.smd subtitle0260.properties 127 | get_strings subtitle/subtitle0262${LANG2}.dat/subtitle0262.smd subtitle0262.properties 128 | get_strings ph1/p100.dat/p100_56f39801_scp.bin p100_56f39801_scp.properties 129 | get_strings ph1/p100.dat/p100_6fc2accc_scp.bin p100_6fc2accc_scp.properties 130 | get_strings ph1/p100.dat/p100_824dfa10_scp.bin p100_824dfa10_scp.properties 131 | get_strings ph1/p100.dat/p100_508c029e_scp.bin p100_508c029e_scp.properties 132 | get_strings ph1/p100.dat/p100_a2a7da53_scp.bin p100_a2a7da53_scp.properties 133 | get_strings subtitle/subtitle0270${LANG2}.dat/subtitle0270.smd subtitle0270.properties 134 | get_strings subtitle/subtitle0280${LANG2}.dat/subtitle0280.smd subtitle0280.properties 135 | get_strings ph1/p100.dat/p100_23622eee_scp.bin p100_23622eee_scp.properties 136 | get_strings st1/r130.dat/r130_e5cfdb23_scp.bin r130_e5cfdb23_scp.properties 137 | get_strings ph1/p100.dat/p100_56e518db_scp.bin p100_56e518db_scp.properties 138 | get_strings subtitle/subtitle0300${LANG2}.dat/subtitle0300.smd subtitle0300.properties 139 | get_strings subtitle/subtitle0301${LANG2}.dat/subtitle0301.smd subtitle0301.properties 140 | get_strings subtitle/subtitleb301${LANG2}.dat/subtitleb301.smd subtitleb301.properties 141 | get_strings ph1/p100.dat/p100_2299a056_scp.bin p100_2299a056_scp.properties 142 | get_strings quest/qab2.dat/qab2_aec178b7_scp.bin qab2_aec178b7_scp.properties 143 | get_strings subtitle/subtitle0310${LANG2}.dat/subtitle0310.smd subtitle0310.properties 144 | get_strings subtitle/subtitle0311${LANG2}.dat/subtitle0311.smd subtitle0311.properties 145 | get_strings subtitle/subtitleb311${LANG2}.dat/subtitleb311.smd subtitleb311.properties 146 | get_strings quest/qab3.dat/qab3_934fd3b1_scp.bin qab3_934fd3b1_scp.properties 147 | get_strings subtitle/subtitle0320${LANG2}.dat/subtitle0320.smd subtitle0320.properties 148 | get_strings subtitle/subtitle0321${LANG2}.dat/subtitle0321.smd subtitle0321.properties 149 | get_strings subtitle/subtitle0322${LANG2}.dat/subtitle0322.smd subtitle0322.properties 150 | get_strings subtitle/subtitle0323${LANG2}.dat/subtitle0323.smd subtitle0323.properties 151 | get_strings subtitle/subtitleb321${LANG2}.dat/subtitleb321.smd subtitleb321.properties 152 | get_strings ph1/p100.dat/p100_73ce9cac_scp.bin p100_73ce9cac_scp.properties 153 | get_strings ph1/p100.dat/p100_adc09aec_scp.bin p100_adc09aec_scp.properties 154 | get_strings ph1/p100.dat/p100_81c8f672_scp.bin p100_81c8f672_scp.properties 155 | get_strings ph2/p200.dat/p200_a2a7da53_scp.bin p200_a2a7da53_scp.properties 156 | get_strings subtitle/subtitle0325${LANG2}.dat/subtitle0325.smd subtitle0325.properties 157 | get_strings subtitle/subtitle0326${LANG2}.dat/subtitle0326.smd subtitle0326.properties 158 | get_strings ph1/p100.dat/p100_47a5d6eb_scp.bin p100_47a5d6eb_scp.properties 159 | get_strings st1/r140.dat/r140_29cb90b_scp.bin r140_29cb90b_scp.properties 160 | get_strings st1/r140.dat/r140_60377331_scp.bin r140_60377331_scp.properties 161 | get_strings st1/r140.dat/r140_82d2caac_scp.bin r140_82d2caac_scp.properties 162 | get_strings st1/r140.dat/r140_cd4fd96a_scp.bin r140_cd4fd96a_scp.properties 163 | get_strings st1/r140.dat/r140_f82d8b66_scp.bin r140_f82d8b66_scp.properties 164 | get_strings ph1/p100.dat/p100_9b15340d_scp.bin p100_9b15340d_scp.properties 165 | get_strings st1/r100.dat/r100_c723351a_scp.bin r100_c723351a_scp.properties 166 | get_strings subtitle/subtitle0330${LANG2}.dat/subtitle0330.smd subtitle0330.properties 167 | get_strings ph2/p200.dat/p200_2e8bdcb0_scp.bin p200_2e8bdcb0_scp.properties 168 | get_strings ph2/p200.dat/p200_886c2178_scp.bin p200_886c2178_scp.properties 169 | get_strings ph2/p200.dat/p200_92dddd6e_scp.bin p200_92dddd6e_scp.properties 170 | get_strings subtitle/subtitle0340${LANG2}.dat/subtitle0340.smd subtitle0340.properties 171 | get_strings subtitle/subtitle0341${LANG2}.dat/subtitle0341.smd subtitle0341.properties 172 | get_strings subtitle/subtitleb341${LANG2}.dat/subtitleb341.smd subtitleb341.properties 173 | get_strings ph2/p200.dat/p200_bb51fdfc_scp.bin p200_bb51fdfc_scp.properties 174 | get_strings subtitle/subtitle0350${LANG2}.dat/subtitle0350.smd subtitle0350.properties 175 | get_strings subtitle/subtitle0351${LANG2}.dat/subtitle0351.smd subtitle0351.properties 176 | get_strings subtitle/subtitle0352${LANG2}.dat/subtitle0352.smd subtitle0352.properties 177 | get_strings subtitle/subtitleb351${LANG2}.dat/subtitleb351.smd subtitleb351.properties 178 | get_strings subtitle/subtitle0360${LANG2}.dat/subtitle0360.smd subtitle0360.properties 179 | get_strings ph2/p200.dat/p200_b99094bd_scp.bin p200_b99094bd_scp.properties 180 | get_strings ph2/p200.dat/p200_20084f1f_scp.bin p200_20084f1f_scp.properties 181 | get_strings ph2/p200.dat/p200_a3d6d2f5_scp.bin p200_a3d6d2f5_scp.properties 182 | get_strings ph2/p200.dat/p200_7c0c6f18_scp.bin p200_7c0c6f18_scp.properties 183 | get_strings ph2/p200.dat/p200_c544d6ad_scp.bin p200_c544d6ad_scp.properties 184 | get_strings ph2/p200.dat/p200_78334de1_scp.bin p200_78334de1_scp.properties 185 | get_strings subtitle/subtitle0370${LANG2}.dat/subtitle0370.smd subtitle0370.properties 186 | get_strings ph2/p200.dat/p200_24125524_scp.bin p200_24125524_scp.properties 187 | get_strings ph2/p200.dat/p200_7398bbfd_scp.bin p200_7398bbfd_scp.properties 188 | get_strings ph2/p200.dat/p200_24194e13_scp.bin p200_24194e13_scp.properties 189 | get_strings ph2/p200.dat/p200_647d1cd7_scp.bin p200_647d1cd7_scp.properties 190 | get_strings ph2/p200.dat/p200_3c562f91_scp.bin p200_3c562f91_scp.properties 191 | get_strings ph2/p200.dat/p200_ff3d446f_scp.bin p200_ff3d446f_scp.properties 192 | get_strings ph2/p200.dat/p200_d0b71b3b_scp.bin p200_d0b71b3b_scp.properties 193 | get_strings st1/r160.dat/r160_3fa0647a_scp.bin r160_3fa0647a_scp.properties 194 | get_strings st1/r160.dat/r160_74d9b777_scp.bin r160_74d9b777_scp.properties 195 | get_strings st1/r160.dat/r160_1557ce81_scp.bin r160_1557ce81_scp.properties 196 | get_strings ph2/p200.dat/p200_71c59d9f_scp.bin p200_71c59d9f_scp.properties 197 | get_strings ph2/p200.dat/p200_8cbb3f1e_scp.bin p200_8cbb3f1e_scp.properties 198 | get_strings st1/r160.dat/r160_7247f0a7_scp.bin r160_7247f0a7_scp.properties 199 | get_strings ph2/p200.dat/p200_2bfce9ed_scp.bin p200_2bfce9ed_scp.properties 200 | get_strings ph2/p200.dat/p200_48a7f0fd_scp.bin p200_48a7f0fd_scp.properties 201 | get_strings st1/r160.dat/r160_307c8a44_scp.bin r160_307c8a44_scp.properties 202 | get_strings st1/r160.dat/r160_f8f21cd2_scp.bin r160_f8f21cd2_scp.properties 203 | get_strings subtitle/subtitle0390${LANG2}.dat/subtitle0390.smd subtitle0390.properties 204 | get_strings subtitle/subtitle0400${LANG2}.dat/subtitle0400.smd subtitle0400.properties 205 | get_strings subtitle/subtitle0410${LANG2}.dat/subtitle0410.smd subtitle0410.properties 206 | get_strings ph2/p200.dat/p200_6ae550e0_scp.bin p200_6ae550e0_scp.properties 207 | get_strings ph2/p200.dat/p200_96e13a06_scp.bin p200_96e13a06_scp.properties 208 | get_strings ph2/p200.dat/p200_ad4026af_scp.bin p200_ad4026af_scp.properties 209 | get_strings ph2/p200.dat/p200_8182a35a_scp.bin p200_8182a35a_scp.properties 210 | get_strings ph2/p200.dat/p200_27db07bb_scp.bin p200_27db07bb_scp.properties 211 | get_strings subtitle/subtitle0440${LANG2}.dat/subtitle0440.smd subtitle0440.properties 212 | get_strings subtitle/subtitle0441${LANG2}.dat/subtitle0441.smd subtitle0441.properties 213 | get_strings subtitle/subtitleb441${LANG2}.dat/subtitleb441.smd subtitleb441.properties 214 | get_strings ph2/p200.dat/p200_20cd934d_scp.bin p200_20cd934d_scp.properties 215 | get_strings ph2/p200.dat/p200_5dfcaace_scp.bin p200_5dfcaace_scp.properties 216 | get_strings ph2/p200.dat/p200_e723b449_scp.bin p200_e723b449_scp.properties 217 | get_strings ph2/p200.dat/p200_a1e11071_scp.bin p200_a1e11071_scp.properties 218 | get_strings ph2/p200.dat/p200_e8fce7cc_scp.bin p200_e8fce7cc_scp.properties 219 | get_strings subtitle/subtitle0460${LANG2}.dat/subtitle0460.smd subtitle0460.properties 220 | get_strings subtitle/subtitle0461${LANG2}.dat/subtitle0461.smd subtitle0461.properties 221 | get_strings subtitle/subtitleb461${LANG2}.dat/subtitleb461.smd subtitleb461.properties 222 | get_strings ph2/p200.dat/p200_4b245f40_scp.bin p200_4b245f40_scp.properties 223 | get_strings subtitle/subtitle0470${LANG2}.dat/subtitle0470.smd subtitle0470.properties 224 | get_strings subtitle/subtitle0471${LANG2}.dat/subtitle0471.smd subtitle0471.properties 225 | get_strings subtitle/subtitleb471${LANG2}.dat/subtitleb471.smd subtitleb471.properties 226 | get_strings ph2/p200.dat/p200_c7ba8911_scp.bin p200_c7ba8911_scp.properties 227 | get_strings ph2/p200.dat/p200_f764463b_scp.bin p200_f764463b_scp.properties 228 | get_strings ph2/p200.dat/p200_a68c4ea9_scp.bin p200_a68c4ea9_scp.properties 229 | get_strings subtitle/subtitle0475${LANG2}.dat/subtitle0475.smd subtitle0475.properties 230 | get_strings ph2/p200.dat/p200_e8cf2a5c_scp.bin p200_e8cf2a5c_scp.properties 231 | get_strings subtitle/subtitle0480${LANG2}.dat/subtitle0480.smd subtitle0480.properties 232 | get_strings subtitle/subtitle0485${LANG2}.dat/subtitle0485.smd subtitle0485.properties 233 | get_strings subtitle/subtitle0420${LANG2}.dat/subtitle0420.smd subtitle0420.properties 234 | get_strings subtitle/subtitle0482${LANG2}.dat/subtitle0482.smd subtitle0482.properties 235 | get_strings subtitle/subtitle0483${LANG2}.dat/subtitle0483.smd subtitle0483.properties 236 | get_strings subtitle/subtitle0490${LANG2}.dat/subtitle0490.smd subtitle0490.properties 237 | get_strings subtitle/subtitle0491${LANG2}.dat/subtitle0491.smd subtitle0491.properties 238 | get_strings ph2/p200.dat/p200_58623dde_scp.bin p200_58623dde_scp.properties 239 | get_strings ph2/p200.dat/p200_d5ac1e7d_scp.bin p200_d5ac1e7d_scp.properties 240 | get_strings subtitle/subtitle0500${LANG2}.dat/subtitle0500.smd subtitle0500.properties 241 | get_strings quest/qab5.dat/qab5_4a1ea1bc_scp.bin qab5_4a1ea1bc_scp.properties 242 | get_strings subtitle/subtitle0520${LANG2}.dat/subtitle0520.smd subtitle0520.properties 243 | get_strings subtitle/subtitle0521${LANG2}.dat/subtitle0521.smd subtitle0521.properties 244 | get_strings ph2/p200.dat/p200_1cc100aa_scp.bin p200_1cc100aa_scp.properties 245 | get_strings subtitle/subtitle0525${LANG2}.dat/subtitle0525.smd subtitle0525.properties 246 | get_strings subtitle/subtitle0526${LANG2}.dat/subtitle0526.smd subtitle0526.properties 247 | get_strings subtitle/subtitle0530${LANG2}.dat/subtitle0530.smd subtitle0530.properties 248 | get_strings subtitle/subtitle0531${LANG2}.dat/subtitle0531.smd subtitle0531.properties 249 | get_strings subtitle/subtitle0540${LANG2}.dat/subtitle0540.smd subtitle0540.properties 250 | get_strings subtitle/subtitle0550${LANG2}.dat/subtitle0550.smd subtitle0550.properties 251 | get_strings subtitle/subtitle0552${LANG2}.dat/subtitle0552.smd subtitle0552.properties 252 | get_strings subtitle/subtitle0502${LANG2}.dat/subtitle0502.smd subtitle0502.properties 253 | get_strings quest/qab6.dat/qab6_69325679_scp.bin qab6_69325679_scp.properties 254 | get_strings ph2/p200.dat/p200_398cde2c_scp.bin p200_398cde2c_scp.properties 255 | get_strings ph2/p200.dat/p200_f1f22ca2_scp.bin p200_f1f22ca2_scp.properties 256 | get_strings ph2/p200.dat/p200_aad478cc_scp.bin p200_aad478cc_scp.properties 257 | get_strings ph2/p200.dat/p200_7914bf_scp.bin p200_7914bf_scp.properties 258 | get_strings subtitle/subtitle0570${LANG2}.dat/subtitle0570.smd subtitle0570.properties 259 | get_strings subtitle/subtitle0571${LANG2}.dat/subtitle0571.smd subtitle0571.properties 260 | get_strings ph2/p200.dat/p200_c44b75b3_scp.bin p200_c44b75b3_scp.properties 261 | get_strings ph2/p200.dat/p200_b4fc12d6_scp.bin p200_b4fc12d6_scp.properties 262 | get_strings ph2/p200.dat/p200_1fcb850d_scp.bin p200_1fcb850d_scp.properties 263 | get_strings ph2/p200.dat/p200_67909aeb_scp.bin p200_67909aeb_scp.properties 264 | get_strings ph2/p200.dat/p200_8806bcb7_scp.bin p200_8806bcb7_scp.properties 265 | get_strings ph2/p200.dat/p200_7793b6d6_scp.bin p200_7793b6d6_scp.properties 266 | get_strings quest/qaba.dat/qaba_a7ed1850_scp.bin qaba_a7ed1850_scp.properties 267 | get_strings ph2/p200.dat/p200_17d05835_scp.bin p200_17d05835_scp.properties 268 | get_strings quest/qabb.dat/qabb_1e5a233e_scp.bin qabb_1e5a233e_scp.properties 269 | get_strings ph2/p200.dat/p200_99454795_scp.bin p200_99454795_scp.properties 270 | get_strings ph2/p200.dat/p200_56645a4b_scp.bin p200_56645a4b_scp.properties 271 | get_strings ph2/p200.dat/p200_9a8a8724_scp.bin p200_9a8a8724_scp.properties 272 | get_strings subtitle/subtitle0590${LANG2}.dat/subtitle0590.smd subtitle0590.properties 273 | get_strings ph2/p200.dat/p200_8767f81e_scp.bin p200_8767f81e_scp.properties 274 | get_strings subtitle/subtitle0600${LANG2}.dat/subtitle0600.smd subtitle0600.properties 275 | get_strings subtitle/subtitle0610${LANG2}.dat/subtitle0610.smd subtitle0610.properties 276 | get_strings subtitle/subtitle0612${LANG2}.dat/subtitle0612.smd subtitle0612.properties 277 | get_strings ph2/p200.dat/p200_40b3c93d_scp.bin p200_40b3c93d_scp.properties 278 | get_strings ph2/p200.dat/p200_c3ab84c7_scp.bin p200_c3ab84c7_scp.properties 279 | get_strings ph2/p200.dat/p200_d0a7f4dc_scp.bin p200_d0a7f4dc_scp.properties 280 | get_strings subtitle/subtitle0630${LANG2}.dat/subtitle0630.smd subtitle0630.properties 281 | get_strings subtitle/subtitle0631${LANG2}.dat/subtitle0631.smd subtitle0631.properties 282 | get_strings ph2/p200.dat/p200_cc694d55_scp.bin p200_cc694d55_scp.properties 283 | get_strings ph2/p200.dat/p200_7a5876f7_scp.bin p200_7a5876f7_scp.properties 284 | get_strings ph2/p200.dat/p200_d75fa9d2_scp.bin p200_d75fa9d2_scp.properties 285 | get_strings subtitle/subtitle0640${LANG2}.dat/subtitle0640.smd subtitle0640.properties 286 | get_strings subtitle/subtitle0650${LANG2}.dat/subtitle0650.smd subtitle0650.properties 287 | get_strings subtitle/subtitle0651${LANG2}.dat/subtitle0651.smd subtitle0651.properties 288 | get_strings subtitle/subtitleb651${LANG2}.dat/subtitleb651.smd subtitleb651.properties 289 | get_strings ph2/p200.dat/p200_dad50fa7_scp.bin p200_dad50fa7_scp.properties 290 | get_strings subtitle/subtitle0655${LANG2}.dat/subtitle0655.smd subtitle0655.properties 291 | get_strings subtitle/subtitle0656${LANG2}.dat/subtitle0656.smd subtitle0656.properties 292 | get_strings subtitle/subtitleb656${LANG2}.dat/subtitleb656.smd subtitleb656.properties 293 | get_strings ph2/p200.dat/p200_9dd3606e_scp.bin p200_9dd3606e_scp.properties 294 | get_strings ph2/p200.dat/p200_6aa3f28e_scp.bin p200_6aa3f28e_scp.properties 295 | get_strings subtitle/subtitle0660${LANG2}.dat/subtitle0660.smd subtitle0660.properties 296 | get_strings subtitle/subtitle0661${LANG2}.dat/subtitle0661.smd subtitle0661.properties 297 | get_strings subtitle/subtitleb661${LANG2}.dat/subtitleb661.smd subtitleb661.properties 298 | get_strings ph2/p200.dat/p200_2311697b_scp.bin p200_2311697b_scp.properties 299 | get_strings ph2/p200.dat/p200_1de99b24_scp.bin p200_1de99b24_scp.properties 300 | get_strings quest/qabd.dat/qabd_18ca8961_scp.bin qabd_18ca8961_scp.properties 301 | get_strings ph2/p200.dat/p200_3456f87_scp.bin p200_3456f87_scp.properties 302 | get_strings ph2/p200.dat/p200_8118914c_scp.bin p200_8118914c_scp.properties 303 | get_strings subtitle/subtitle0670${LANG2}.dat/subtitle0670.smd subtitle0670.properties 304 | get_strings subtitle/subtitle0671${LANG2}.dat/subtitle0671.smd subtitle0671.properties 305 | get_strings subtitle/subtitleb671${LANG2}.dat/subtitleb671.smd subtitleb671.properties 306 | get_strings ph2/p200.dat/p200_5a63902e_scp.bin p200_5a63902e_scp.properties 307 | get_strings subtitle/subtitle0680${LANG2}.dat/subtitle0680.smd subtitle0680.properties 308 | get_strings subtitle/subtitle0682${LANG2}.dat/subtitle0682.smd subtitle0682.properties 309 | get_strings ph2/p200.dat/p200_2fb68036_scp.bin p200_2fb68036_scp.properties 310 | get_strings subtitle/subtitle0690${LANG2}.dat/subtitle0690.smd subtitle0690.properties 311 | get_strings subtitle/subtitle0692${LANG2}.dat/subtitle0692.smd subtitle0692.properties 312 | get_strings subtitle/subtitle0700${LANG2}.dat/subtitle0700.smd subtitle0700.properties 313 | get_strings subtitle/subtitle0702${LANG2}.dat/subtitle0702.smd subtitle0702.properties 314 | get_strings ph3/p300.dat/p300_f80fe22d_scp.bin p300_f80fe22d_scp.properties 315 | get_strings subtitle/subtitle0642${LANG2}.dat/subtitle0642.smd subtitle0642.properties 316 | get_strings subtitle/subtitle0693${LANG2}.dat/subtitle0693.smd subtitle0693.properties 317 | get_strings subtitle/subtitle0694${LANG2}.dat/subtitle0694.smd subtitle0694.properties 318 | get_strings subtitle/subtitle0720${LANG2}.dat/subtitle0720.smd subtitle0720.properties 319 | get_strings subtitle/subtitle0722${LANG2}.dat/subtitle0722.smd subtitle0722.properties 320 | get_strings subtitle/subtitle0730${LANG2}.dat/subtitle0730.smd subtitle0730.properties 321 | get_strings ph3/p300.dat/p300_abb1d768_scp.bin p300_abb1d768_scp.properties 322 | get_strings ph3/p300.dat/p300_69ab2de6_scp.bin p300_69ab2de6_scp.properties 323 | get_strings ph3/p300.dat/p300_fe415e44_scp.bin p300_fe415e44_scp.properties 324 | get_strings ph3/p300.dat/p300_e9106cc6_scp.bin p300_e9106cc6_scp.properties 325 | get_strings subtitle/subtitle0760${LANG2}.dat/subtitle0760.smd subtitle0760.properties 326 | get_strings subtitle/subtitle0761${LANG2}.dat/subtitle0761.smd subtitle0761.properties 327 | get_strings subtitle/subtitle0770${LANG2}.dat/subtitle0770.smd subtitle0770.properties 328 | get_strings subtitle/subtitle0771${LANG2}.dat/subtitle0771.smd subtitle0771.properties 329 | get_strings subtitle/subtitle0780${LANG2}.dat/subtitle0780.smd subtitle0780.properties 330 | get_strings subtitle/subtitle0781${LANG2}.dat/subtitle0781.smd subtitle0781.properties 331 | get_strings quest/qad0.dat/qad0_c493efec_scp.bin qad0_c493efec_scp.properties 332 | get_strings ph3/p300.dat/p300_a60ff1fc_scp.bin p300_a60ff1fc_scp.properties 333 | get_strings subtitle/subtitle0790${LANG2}.dat/subtitle0790.smd subtitle0790.properties 334 | get_strings subtitle/subtitle0791${LANG2}.dat/subtitle0791.smd subtitle0791.properties 335 | get_strings subtitle/subtitle0792${LANG2}.dat/subtitle0792.smd subtitle0792.properties 336 | get_strings ph3/p300.dat/p300_d578eca9_scp.bin p300_d578eca9_scp.properties 337 | get_strings subtitle/subtitle0800${LANG2}.dat/subtitle0800.smd subtitle0800.properties 338 | get_strings subtitle/subtitle0810${LANG2}.dat/subtitle0810.smd subtitle0810.properties 339 | get_strings subtitle/subtitle0811${LANG2}.dat/subtitle0811.smd subtitle0811.properties 340 | get_strings ph3/p300.dat/p300_26ad4903_scp.bin p300_26ad4903_scp.properties 341 | get_strings subtitle/subtitle0820${LANG2}.dat/subtitle0820.smd subtitle0820.properties 342 | get_strings subtitle/subtitle0830${LANG2}.dat/subtitle0830.smd subtitle0830.properties 343 | get_strings ph3/p300.dat/p300_8352dd61_scp.bin p300_8352dd61_scp.properties 344 | get_strings subtitle/subtitle0835${LANG2}.dat/subtitle0835.smd subtitle0835.properties 345 | get_strings subtitle/subtitle0836${LANG2}.dat/subtitle0836.smd subtitle0836.properties 346 | get_strings ph3/p300.dat/p300_1cc46857_scp.bin p300_1cc46857_scp.properties 347 | get_strings ph3/p300.dat/p300_a34d9d8a_scp.bin p300_a34d9d8a_scp.properties 348 | get_strings subtitle/subtitle0850${LANG2}.dat/subtitle0850.smd subtitle0850.properties 349 | get_strings ph3/p300.dat/p300_2ac25a34_scp.bin p300_2ac25a34_scp.properties 350 | get_strings subtitle/subtitle0855${LANG2}.dat/subtitle0855.smd subtitle0855.properties 351 | get_strings ph3/p300.dat/p300_e47baab_scp.bin p300_e47baab_scp.properties 352 | get_strings ph3/p300.dat/p300_73ee82d4_scp.bin p300_73ee82d4_scp.properties 353 | get_strings subtitle/subtitle0860${LANG2}.dat/subtitle0860.smd subtitle0860.properties 354 | get_strings subtitle/subtitle0861${LANG2}.dat/subtitle0861.smd subtitle0861.properties 355 | get_strings ph3/p300.dat/p300_1c94bbb3_scp.bin p300_1c94bbb3_scp.properties 356 | get_strings ph3/p300.dat/p300_969b4cd4_scp.bin p300_969b4cd4_scp.properties 357 | get_strings ph3/p300.dat/p300_52095a27_scp.bin p300_52095a27_scp.properties 358 | get_strings st1/r140.dat/r140_657c1219_scp.bin r140_657c1219_scp.properties 359 | get_strings ph3/p300.dat/p300_5f56e621_scp.bin p300_5f56e621_scp.properties 360 | get_strings subtitle/subtitle0870${LANG2}.dat/subtitle0870.smd subtitle0870.properties 361 | get_strings subtitle/subtitle0871${LANG2}.dat/subtitle0871.smd subtitle0871.properties 362 | get_strings ph3/p300.dat/p300_d7fb6a72_scp.bin p300_d7fb6a72_scp.properties 363 | get_strings subtitle/subtitle0875${LANG2}.dat/subtitle0875.smd subtitle0875.properties 364 | get_strings quest/qad1.dat/qad1_55fcb9b3_scp.bin qad1_55fcb9b3_scp.properties 365 | get_strings subtitle/subtitle0880${LANG2}.dat/subtitle0880.smd subtitle0880.properties 366 | get_strings ph3/p300.dat/p300_a80afa1d_scp.bin p300_a80afa1d_scp.properties 367 | get_strings subtitle/subtitle0900${LANG2}.dat/subtitle0900.smd subtitle0900.properties 368 | get_strings subtitle/subtitle0901${LANG2}.dat/subtitle0901.smd subtitle0901.properties 369 | get_strings ph3/p300.dat/p300_58e3f469_scp.bin p300_58e3f469_scp.properties 370 | get_strings ph3/p300.dat/p300_b863f435_scp.bin p300_b863f435_scp.properties 371 | get_strings quest/qb20.dat/qb20_42c8efa_scp.bin qb20_42c8efa_scp.properties 372 | get_strings quest/qb20.dat/qb20_91cf1fa5_scp.bin qb20_91cf1fa5_scp.properties 373 | get_strings st2/r200.dat/r200_427ea0a7_scp.bin r200_427ea0a7_scp.properties 374 | get_strings ph3/p300.dat/p300_4ac43a7f_scp.bin p300_4ac43a7f_scp.properties 375 | get_strings ph3/p300.dat/p300_f29af5ee_scp.bin p300_f29af5ee_scp.properties 376 | get_strings subtitle/subtitle0910${LANG2}.dat/subtitle0910.smd subtitle0910.properties 377 | get_strings ph3/p300.dat/p300_59a32047_scp.bin p300_59a32047_scp.properties 378 | get_strings ph3/p300.dat/p300_ebb2aa60_scp.bin p300_ebb2aa60_scp.properties 379 | get_strings subtitle/subtitle0920${LANG2}.dat/subtitle0920.smd subtitle0920.properties 380 | get_strings subtitle/subtitle0921${LANG2}.dat/subtitle0921.smd subtitle0921.properties 381 | get_strings subtitle/subtitle0926${LANG2}.dat/subtitle0926.smd subtitle0926.properties 382 | get_strings subtitle/subtitle0930${LANG2}.dat/subtitle0930.smd subtitle0930.properties 383 | get_strings subtitle/subtitle0931${LANG2}.dat/subtitle0931.smd subtitle0931.properties 384 | get_strings ph3/p300.dat/p300_2b0332c8_scp.bin p300_2b0332c8_scp.properties 385 | get_strings ph3/p300.dat/p300_8f18b72c_scp.bin p300_8f18b72c_scp.properties 386 | get_strings subtitle/subtitle0940${LANG2}.dat/subtitle0940.smd subtitle0940.properties 387 | get_strings ph3/p300.dat/p300_78ebd792_scp.bin p300_78ebd792_scp.properties 388 | get_strings ph3/p300.dat/p300_4fce2323_scp.bin p300_4fce2323_scp.properties 389 | get_strings subtitle/subtitle0950${LANG2}.dat/subtitle0950.smd subtitle0950.properties 390 | get_strings subtitle/subtitle0951${LANG2}.dat/subtitle0951.smd subtitle0951.properties 391 | get_strings ph3/p300.dat/p300_abb0feab_scp.bin p300_abb0feab_scp.properties 392 | get_strings ph3/p300.dat/p300_7677d46d_scp.bin p300_7677d46d_scp.properties 393 | get_strings ph3/p300.dat/p300_33eec348_scp.bin p300_33eec348_scp.properties 394 | get_strings ph3/p300.dat/p300_312ca323_scp.bin p300_312ca323_scp.properties 395 | get_strings core/corehap.dat/global_d595bcd1_scp.bin global_d595bcd1_scp.properties 396 | get_strings ph3/p300.dat/p300_b01535dd_scp.bin p300_b01535dd_scp.properties 397 | get_strings subtitle/subtitle0935${LANG2}.dat/subtitle0935.smd subtitle0935.properties 398 | get_strings subtitle/subtitle0936${LANG2}.dat/subtitle0936.smd subtitle0936.properties 399 | get_strings subtitle/subtitle0960${LANG2}.dat/subtitle0960.smd subtitle0960.properties 400 | get_strings subtitle/subtitle0961${LANG2}.dat/subtitle0961.smd subtitle0961.properties 401 | get_strings ph3/p300.dat/p300_6f88066d_scp.bin p300_6f88066d_scp.properties 402 | get_strings ph3/p300.dat/p300_454d3c27_scp.bin p300_454d3c27_scp.properties 403 | get_strings subtitle/subtitle0970${LANG2}.dat/subtitle0970.smd subtitle0970.properties 404 | get_strings quest/qad2.dat/qad2_e6ef8eaf_scp.bin qad2_e6ef8eaf_scp.properties 405 | get_strings st1/r140.dat/r140_7e0bd84f_scp.bin r140_7e0bd84f_scp.properties 406 | get_strings ph3/p300.dat/p300_fb6b9581_scp.bin p300_fb6b9581_scp.properties 407 | get_strings subtitle/subtitle0990${LANG2}.dat/subtitle0990.smd subtitle0990.properties 408 | get_strings ph3/p300.dat/p300_838131a5_scp.bin p300_838131a5_scp.properties 409 | get_strings subtitle/subtitle1000${LANG2}.dat/subtitle1000.smd subtitle1000.properties 410 | get_strings subtitle/subtitle1001${LANG2}.dat/subtitle1001.smd subtitle1001.properties 411 | get_strings subtitle/subtitle1010${LANG2}.dat/subtitle1010.smd subtitle1010.properties 412 | get_strings ph3/p300.dat/p300_540e0da_scp.bin p300_540e0da_scp.properties 413 | get_strings ph3/p300.dat/p300_e3d05ab7_scp.bin p300_e3d05ab7_scp.properties 414 | get_strings ph3/p300.dat/p300_dd8b37bd_scp.bin p300_dd8b37bd_scp.properties 415 | get_strings ph3/p300.dat/p300_9d8df164_scp.bin p300_9d8df164_scp.properties 416 | get_strings ph3/p300.dat/p300_af5fb37c_scp.bin p300_af5fb37c_scp.properties 417 | get_strings ph3/p300.dat/p300_d48627b4_scp.bin p300_d48627b4_scp.properties 418 | get_strings subtitle/subtitle1030${LANG2}.dat/subtitle1030.smd subtitle1030.properties 419 | get_strings ph3/p300.dat/p300_34ffac43_scp.bin p300_34ffac43_scp.properties 420 | get_strings ph3/p300.dat/p300_2460bab4_scp.bin p300_2460bab4_scp.properties 421 | get_strings subtitle/subtitle1040${LANG2}.dat/subtitle1040.smd subtitle1040.properties 422 | get_strings subtitle/subtitle1041${LANG2}.dat/subtitle1041.smd subtitle1041.properties 423 | get_strings ph3/p300.dat/p300_fe580523_scp.bin p300_fe580523_scp.properties 424 | get_strings subtitle/subtitle1050${LANG2}.dat/subtitle1050.smd subtitle1050.properties 425 | get_strings subtitle/subtitle1051${LANG2}.dat/subtitle1051.smd subtitle1051.properties 426 | get_strings ph3/p300.dat/p300_be18477d_scp.bin p300_be18477d_scp.properties 427 | get_strings subtitle/subtitle1060${LANG2}.dat/subtitle1060.smd subtitle1060.properties 428 | get_strings ph3/p300.dat/p300_7220e53d_scp.bin p300_7220e53d_scp.properties 429 | get_strings ph3/p300.dat/p300_79a7d0d0_scp.bin p300_79a7d0d0_scp.properties 430 | get_strings subtitle/subtitle1080${LANG2}.dat/subtitle1080.smd subtitle1080.properties 431 | get_strings subtitle/subtitle1090${LANG2}.dat/subtitle1090.smd subtitle1090.properties 432 | get_strings subtitle/subtitle1091${LANG2}.dat/subtitle1091.smd subtitle1091.properties 433 | get_strings ph3/p300.dat/p300_cc42e29e_scp.bin p300_cc42e29e_scp.properties 434 | get_strings quest/qad6.dat/qad6_b6255483_scp.bin qad6_b6255483_scp.properties 435 | get_strings ph3/p300.dat/p300_d86d80b1_scp.bin p300_d86d80b1_scp.properties 436 | get_strings subtitle/subtitle1100${LANG2}.dat/subtitle1100.smd subtitle1100.properties 437 | get_strings ph3/p300.dat/p300_fb5ab100_scp.bin p300_fb5ab100_scp.properties 438 | get_strings ph3/p300.dat/p300_62973173_scp.bin p300_62973173_scp.properties 439 | get_strings subtitle/subtitle1120${LANG2}.dat/subtitle1120.smd subtitle1120.properties 440 | get_strings subtitle/subtitle1121${LANG2}.dat/subtitle1121.smd subtitle1121.properties 441 | get_strings ph3/p300.dat/p300_249dcf6a_scp.bin p300_249dcf6a_scp.properties 442 | get_strings subtitle/subtitle1125${LANG2}.dat/subtitle1125.smd subtitle1125.properties 443 | get_strings ph3/p300.dat/p300_f0e6bd59_scp.bin p300_f0e6bd59_scp.properties 444 | get_strings ph3/p300.dat/p300_95a183ba_scp.bin p300_95a183ba_scp.properties 445 | get_strings ph3/p300.dat/p300_24fd47f4_scp.bin p300_24fd47f4_scp.properties 446 | get_strings subtitle/subtitle1150${LANG2}.dat/subtitle1150.smd subtitle1150.properties 447 | get_strings subtitle/subtitle1160${LANG2}.dat/subtitle1160.smd subtitle1160.properties 448 | get_strings ph3/p300.dat/p300_50eb25b8_scp.bin p300_50eb25b8_scp.properties 449 | get_strings ph3/p300.dat/p300_ac91bbe4_scp.bin p300_ac91bbe4_scp.properties 450 | get_strings ph3/p300.dat/p300_d913dcc1_scp.bin p300_d913dcc1_scp.properties 451 | get_strings subtitle/subtitle1180${LANG2}.dat/subtitle1180.smd subtitle1180.properties 452 | get_strings subtitle/subtitle1181${LANG2}.dat/subtitle1181.smd subtitle1181.properties 453 | get_strings ph3/p300.dat/p300_df90c81a_scp.bin p300_df90c81a_scp.properties 454 | get_strings ph3/p300.dat/p300_54b1765c_scp.bin p300_54b1765c_scp.properties 455 | get_strings ph3/p300.dat/p300_9b77492c_scp.bin p300_9b77492c_scp.properties 456 | get_strings quest/qaeb.dat/qaeb_98b8e891_scp.bin qaeb_98b8e891_scp.properties 457 | get_strings subtitle/subtitle1190${LANG2}.dat/subtitle1190.smd subtitle1190.properties 458 | get_strings subtitle/subtitle1191${LANG2}.dat/subtitle1191.smd subtitle1191.properties 459 | get_strings ph3/p300.dat/p300_4a0a3acc_scp.bin p300_4a0a3acc_scp.properties 460 | get_strings ph3/p300.dat/p300_157c0c19_scp.bin p300_157c0c19_scp.properties 461 | get_strings subtitle/subtitle1210${LANG2}.dat/subtitle1210.smd subtitle1210.properties 462 | get_strings subtitle/subtitle1211${LANG2}.dat/subtitle1211.smd subtitle1211.properties 463 | get_strings ph3/p300.dat/p300_802d17e9_scp.bin p300_802d17e9_scp.properties 464 | get_strings ph3/p300.dat/p300_fca61b8d_scp.bin p300_fca61b8d_scp.properties 465 | get_strings subtitle/subtitle1220${LANG2}.dat/subtitle1220.smd subtitle1220.properties 466 | get_strings subtitle/subtitle1221${LANG2}.dat/subtitle1221.smd subtitle1221.properties 467 | get_strings ph3/p300.dat/p300_544f9315_scp.bin p300_544f9315_scp.properties 468 | get_strings subtitle/subtitle1230${LANG2}.dat/subtitle1230.smd subtitle1230.properties 469 | get_strings ph3/p300.dat/p300_987be645_scp.bin p300_987be645_scp.properties 470 | get_strings subtitle/subtitle1232${LANG2}.dat/subtitle1232.smd subtitle1232.properties 471 | get_strings subtitle/subtitle1233${LANG2}.dat/subtitle1233.smd subtitle1233.properties 472 | get_strings subtitle/subtitle1234${LANG2}.dat/subtitle1234.smd subtitle1234.properties 473 | get_strings subtitle/subtitle1235${LANG2}.dat/subtitle1235.smd subtitle1235.properties 474 | get_strings ph3/p300.dat/p300_68b9c234_scp.bin p300_68b9c234_scp.properties 475 | get_strings subtitle/subtitle1240${LANG2}.dat/subtitle1240.smd subtitle1240.properties 476 | get_strings subtitle/subtitle1241${LANG2}.dat/subtitle1241.smd subtitle1241.properties 477 | get_strings ph3/p300.dat/p300_10112854_scp.bin p300_10112854_scp.properties 478 | get_strings quest/qaef.dat/qaef_10112854_scp.bin qaef_10112854_scp.properties 479 | get_strings subtitle/subtitle1250${LANG2}.dat/subtitle1250.smd subtitle1250.properties 480 | get_strings subtitle/subtitle1260${LANG2}.dat/subtitle1260.smd subtitle1260.properties 481 | get_strings ph3/p300.dat/p300_d2ca712b_scp.bin p300_d2ca712b_scp.properties 482 | get_strings phf/pf31.dat/pf31_d2ca712b_scp.bin pf31_d2ca712b_scp.properties 483 | get_strings subtitle/subtitle1270${LANG2}.dat/subtitle1270.smd subtitle1270.properties 484 | get_strings ph3/p300.dat/p300_7de5c329_scp.bin p300_7de5c329_scp.properties 485 | get_strings phf/pf10.dat/pf10_7de5c329_scp.bin pf10_7de5c329_scp.properties 486 | get_strings st1/r110.dat/r110_be7ebe38_scp.bin r110_be7ebe38_scp.properties 487 | get_strings st2/r200.dat/r200_d52e3bf5_scp.bin r200_d52e3bf5_scp.properties 488 | get_strings ph4/p400.dat/p400_b0e38442_scp.bin p400_b0e38442_scp.properties 489 | get_strings phf/pf30.dat/pf30_148bec7a_scp.bin pf30_148bec7a_scp.properties 490 | get_strings quest/q020.dat/q020_404eba3d_scp.bin q020_404eba3d_scp.properties 491 | get_strings quest/q031.dat/q031_b551328a_scp.bin q031_b551328a_scp.properties 492 | get_strings quest/q032.dat/q032_94bdfeb7_scp.bin q032_94bdfeb7_scp.properties 493 | get_strings st2/r200.dat/r200_e684ee2d_scp.bin r200_e684ee2d_scp.properties 494 | get_strings quest/q040.dat/q040_cf7c14d9_scp.bin q040_cf7c14d9_scp.properties 495 | get_strings st1/r140.dat/r140_9fbdc6a2_scp.bin r140_9fbdc6a2_scp.properties 496 | get_strings st1/r140.dat/r140_dc76121c_scp.bin r140_dc76121c_scp.properties 497 | get_strings quest/q070.dat/q070_fb360535_scp.bin q070_fb360535_scp.properties 498 | get_strings quest/q071.dat/q071_1a17171a_scp.bin q071_1a17171a_scp.properties 499 | get_strings st1/r160.dat/r160_19656865_scp.bin r160_19656865_scp.properties 500 | get_strings st1/r160.dat/r160_e290faf0_scp.bin r160_e290faf0_scp.properties 501 | get_strings st1/r170.dat/r170_e7cef294_scp.bin r170_e7cef294_scp.properties 502 | get_strings st1/r150.dat/r150_f100866e_scp.bin r150_f100866e_scp.properties 503 | get_strings quest/q080.dat/q080_64afc72a_scp.bin q080_64afc72a_scp.properties 504 | get_strings quest/q090.dat/q090_11b12a94_scp.bin q090_11b12a94_scp.properties 505 | get_strings quest/q090.dat/q090_86062922_scp.bin q090_86062922_scp.properties 506 | get_strings subtitle/subtitle1290${LANG2}.dat/subtitle1290.smd subtitle1290.properties 507 | get_strings quest/q091.dat/q091_def6c866_scp.bin q091_def6c866_scp.properties 508 | get_strings quest/q091.dat/q091_402dfd2e_scp.bin q091_402dfd2e_scp.properties 509 | get_strings quest/q091.dat/q091_e03615dd_scp.bin q091_e03615dd_scp.properties 510 | get_strings subtitle/subtitle1300${LANG2}.dat/subtitle1300.smd subtitle1300.properties 511 | get_strings quest/q092.dat/q092_3cd7f934_scp.bin q092_3cd7f934_scp.properties 512 | get_strings quest/q092.dat/q092_35330df_scp.bin q092_35330df_scp.properties 513 | get_strings subtitle/subtitle1310${LANG2}.dat/subtitle1310.smd subtitle1310.properties 514 | get_strings quest/q095.dat/q095_fc4d3b85_scp.bin q095_fc4d3b85_scp.properties 515 | get_strings ph4/p400.dat/p400_fc21ced3_scp.bin p400_fc21ced3_scp.properties 516 | get_strings ph4/p400.dat/p400_3af366c3_scp.bin p400_3af366c3_scp.properties 517 | get_strings quest/qc50.dat/qc50_de375136_scp.bin qc50_de375136_scp.properties 518 | get_strings ph4/p400.dat/p400_5b4661f4_scp.bin p400_5b4661f4_scp.properties 519 | get_strings ph4/p400.dat/p400_42374ea5_scp.bin p400_42374ea5_scp.properties 520 | get_strings phf/pf60.dat/pf60_149e7cbe_scp.bin pf60_149e7cbe_scp.properties 521 | get_strings subtitle/subtitle1320${LANG2}.dat/subtitle1320.smd subtitle1320.properties 522 | get_strings quest/q100.dat/q100_f4f7e973_scp.bin q100_f4f7e973_scp.properties 523 | get_strings quest/q101.dat/q101_5be5b4cc_scp.bin q101_5be5b4cc_scp.properties 524 | get_strings quest/q102.dat/q102_28e223f7_scp.bin q102_28e223f7_scp.properties 525 | get_strings quest/q103.dat/q103_d2b3f5a6_scp.bin q103_d2b3f5a6_scp.properties 526 | get_strings quest/q104.dat/q104_e9ff21ee_scp.bin q104_e9ff21ee_scp.properties 527 | get_strings quest/q110.dat/q110_171236f0_scp.bin q110_171236f0_scp.properties 528 | get_strings st1/r140.dat/r140_ea0da2aa_scp.bin r140_ea0da2aa_scp.properties 529 | get_strings quest/q120.dat/q120_8dcd7a1a_scp.bin q120_8dcd7a1a_scp.properties 530 | get_strings quest/q121.dat/q121_70545c1f_scp.bin q121_70545c1f_scp.properties 531 | get_strings st1/r110.dat/r110_6b1cbecb_scp.bin r110_6b1cbecb_scp.properties 532 | get_strings quest/q122.dat/q122_3a5128c8_scp.bin q122_3a5128c8_scp.properties 533 | get_strings quest/q123.dat/q123_6fde04e_scp.bin q123_6fde04e_scp.properties 534 | get_strings quest/q130.dat/q130_b68bfe22_scp.bin q130_b68bfe22_scp.properties 535 | get_strings quest/qc30.dat/qc30_fde14379_scp.bin qc30_fde14379_scp.properties 536 | get_strings quest/q140.dat/q140_7cda31e_scp.bin q140_7cda31e_scp.properties 537 | get_strings quest/q150.dat/q150_d31e5833_scp.bin q150_d31e5833_scp.properties 538 | get_strings quest/q160.dat/q160_d8b9d0be_scp.bin q160_d8b9d0be_scp.properties 539 | get_strings quest/q162.dat/q162_fc7da4a2_scp.bin q162_fc7da4a2_scp.properties 540 | get_strings quest/q170.dat/q170_96333b78_scp.bin q170_96333b78_scp.properties 541 | get_strings quest/q171.dat/q171_12f2963a_scp.bin q171_12f2963a_scp.properties 542 | get_strings quest/q181.dat/q181_746d944f_scp.bin q181_746d944f_scp.properties 543 | get_strings quest/q180.dat/q180_2d2126d2_scp.bin q180_2d2126d2_scp.properties 544 | get_strings quest/q210.dat/q210_a6306d6c_scp.bin q210_a6306d6c_scp.properties 545 | get_strings st2/r200.dat/r200_c832af28_scp.bin r200_c832af28_scp.properties 546 | get_strings quest/q220.dat/q220_e880784a_scp.bin q220_e880784a_scp.properties 547 | get_strings quest/q221.dat/q221_b113244a_scp.bin q221_b113244a_scp.properties 548 | get_strings quest/q222.dat/q222_f8217e42_scp.bin q222_f8217e42_scp.properties 549 | get_strings ph3/p300.dat/p300_f4f38872_scp.bin p300_f4f38872_scp.properties 550 | get_strings wd1/g11516.dat/g11516_2ccba2ea_scp.bin g11516_2ccba2ea_scp.properties 551 | get_strings st1/r140.dat/r140_336c5af9_scp.bin r140_336c5af9_scp.properties 552 | get_strings quest/q290.dat/q290_e15f2fa1_scp.bin q290_e15f2fa1_scp.properties 553 | get_strings st5/r530.dat/r530_3c8107d_scp.bin r530_3c8107d_scp.properties 554 | get_strings quest/q300.dat/q300_5f9ed04e_scp.bin q300_5f9ed04e_scp.properties 555 | get_strings quest/q330.dat/q330_21f485e_scp.bin q330_21f485e_scp.properties 556 | get_strings quest/q330.dat/q330_70a701da_scp.bin q330_70a701da_scp.properties 557 | get_strings quest/q330.dat/q330_9bafd382_scp.bin q330_9bafd382_scp.properties 558 | get_strings quest/q330.dat/q330_b853020f_scp.bin q330_b853020f_scp.properties 559 | get_strings quest/q330.dat/q330_ee317264_scp.bin q330_ee317264_scp.properties 560 | get_strings subtitle/subtitle1280${LANG2}.dat/subtitle1280.smd subtitle1280.properties 561 | get_strings quest/q340.dat/q340_5620eb59_scp.bin q340_5620eb59_scp.properties 562 | get_strings quest/q360.dat/q360_8efed5ef_scp.bin q360_8efed5ef_scp.properties 563 | get_strings quest/qc10.dat/qc10_ea55109b_scp.bin qc10_ea55109b_scp.properties 564 | get_strings quest/qc11.dat/qc11_e05e7f97_scp.bin qc11_e05e7f97_scp.properties 565 | get_strings quest/qc12.dat/qc12_9b9e9b86_scp.bin qc12_9b9e9b86_scp.properties 566 | get_strings quest/q400.dat/q400_1f6199eb_scp.bin q400_1f6199eb_scp.properties 567 | get_strings quest/q400.dat/q400_21ca35cb_scp.bin q400_21ca35cb_scp.properties 568 | get_strings quest/q400.dat/q400_48d76c20_scp.bin q400_48d76c20_scp.properties 569 | get_strings quest/q400.dat/q400_fc5b48ad_scp.bin q400_fc5b48ad_scp.properties 570 | get_strings quest/q401.dat/q401_643e5418_scp.bin q401_643e5418_scp.properties 571 | get_strings quest/q403.dat/q403_5d43ba8b_scp.bin q403_5d43ba8b_scp.properties 572 | get_strings quest/q410.dat/q410_4f2b901a_scp.bin q410_4f2b901a_scp.properties 573 | get_strings quest/q440.dat/q440_3b4ef61d_scp.bin q440_3b4ef61d_scp.properties 574 | get_strings st1/r160.dat/r160_dc20cee5_scp.bin r160_dc20cee5_scp.properties 575 | get_strings quest/q500.dat/q500_8446c06e_scp.bin q500_8446c06e_scp.properties 576 | get_strings st1/r130.dat/r130_12b5a85a_scp.bin r130_12b5a85a_scp.properties 577 | get_strings quest/q520.dat/q520_afd5aa67_scp.bin q520_afd5aa67_scp.properties 578 | get_strings quest/q532.dat/q532_65ff89bf_scp.bin q532_65ff89bf_scp.properties 579 | get_strings quest/q540.dat/q540_e1207097_scp.bin q540_e1207097_scp.properties 580 | get_strings quest/q550.dat/q550_688e8050_scp.bin q550_688e8050_scp.properties 581 | get_strings quest/q560.dat/q560_291dbe71_scp.bin q560_291dbe71_scp.properties 582 | get_strings quest/q561.dat/q561_74b9a716_scp.bin q561_74b9a716_scp.properties 583 | get_strings quest/q562.dat/q562_e10ec9ab_scp.bin q562_e10ec9ab_scp.properties 584 | get_strings st1/r110.dat/r110_4ebc3b22_scp.bin r110_4ebc3b22_scp.properties 585 | get_strings quest/q590.dat/q590_13ffe891_scp.bin q590_13ffe891_scp.properties 586 | get_strings quest/q720.dat/q720_bbe0d32e_scp.bin q720_bbe0d32e_scp.properties 587 | get_strings quest/q640.dat/q640_ccd60068_scp.bin q640_ccd60068_scp.properties 588 | get_strings quest/q650.dat/q650_96497077_scp.bin q650_96497077_scp.properties 589 | get_strings quest/q651.dat/q651_87a1f20b_scp.bin q651_87a1f20b_scp.properties 590 | get_strings quest/q652.dat/q652_4e20ab43_scp.bin q652_4e20ab43_scp.properties 591 | get_strings core/corehap.dat/global_60efb803_scp.bin global_60efb803_scp.properties 592 | get_strings quest/q660.dat/q660_f737718_scp.bin q660_f737718_scp.properties 593 | get_strings quest/q680.dat/q680_51d704e4_scp.bin q680_51d704e4_scp.properties 594 | get_strings st2/r200.dat/r200_d4dad831_scp.bin r200_d4dad831_scp.properties 595 | get_strings quest/q770.dat/q770_59f68d25_scp.bin q770_59f68d25_scp.properties 596 | get_strings quest/q800.dat/q800_bc7a2755_scp.bin q800_bc7a2755_scp.properties 597 | get_strings quest/q801.dat/q801_6c8f629a_scp.bin q801_6c8f629a_scp.properties 598 | get_strings st1/r140.dat/r140_49e73635_scp.bin r140_49e73635_scp.properties 599 | get_strings quest/q900.dat/q900_626a2689_scp.bin q900_626a2689_scp.properties 600 | get_strings quest/q910.dat/q910_8d8ebfae_scp.bin q910_8d8ebfae_scp.properties 601 | get_strings ph3/p300.dat/p300_4716685f_scp.bin p300_4716685f_scp.properties 602 | get_strings ph3/p300.dat/p300_e6cf440a_scp.bin p300_e6cf440a_scp.properties 603 | get_strings ph1/p100.dat/p100_264b174c_scp.bin p100_264b174c_scp.properties 604 | get_strings quest/q920.dat/q920_e5072c9_scp.bin q920_e5072c9_scp.properties 605 | get_strings st1/r170.dat/r170_261956fa_scp.bin r170_261956fa_scp.properties 606 | get_strings st1/r150.dat/r150_df579346_scp.bin r150_df579346_scp.properties 607 | get_strings core/corehap.dat/global_638e40c8_scp.bin global_638e40c8_scp.properties 608 | get_strings subtitle/subtitle1400${LANG2}.dat/subtitle1400.smd subtitle1400.properties 609 | get_strings subtitle/subtitle1402${LANG2}.dat/subtitle1402.smd subtitle1402.properties 610 | get_strings quest/qb40.dat/qb40_f2a5ded9_scp.bin qb40_f2a5ded9_scp.properties 611 | get_strings quest/qb40.dat/qb40_b490bdc_scp.bin qb40_b490bdc_scp.properties 612 | get_strings st1/r110.dat/r110_7fe2a715_scp.bin r110_7fe2a715_scp.properties 613 | get_strings quest/qb40.dat/qb40_ff6d92e9_scp.bin qb40_ff6d92e9_scp.properties 614 | get_strings quest/qb40.dat/qb40_9403a9bc_scp.bin qb40_9403a9bc_scp.properties 615 | get_strings ph3/p300.dat/p300_22633b31_scp.bin p300_22633b31_scp.properties 616 | get_strings ph3/p300.dat/p300_ae2eada6_scp.bin p300_ae2eada6_scp.properties 617 | get_strings ph3/p300.dat/p300_d2de713_scp.bin p300_d2de713_scp.properties 618 | get_strings ph3/p300.dat/p300_c0c1e86c_scp.bin p300_c0c1e86c_scp.properties 619 | get_strings ph3/p300.dat/p300_e4c7a829_scp.bin p300_e4c7a829_scp.properties 620 | get_strings quest/qb40.dat/qb40_f7708d83_scp.bin qb40_f7708d83_scp.properties 621 | get_strings st1/r160.dat/r160_441c44e3_scp.bin r160_441c44e3_scp.properties 622 | get_strings st1/r160.dat/r160_7cde1b3f_scp.bin r160_7cde1b3f_scp.properties 623 | get_strings st1/r110.dat/r110_7a562cb9_scp.bin r110_7a562cb9_scp.properties 624 | get_strings st1/r110.dat/r110_dd7422a2_scp.bin r110_dd7422a2_scp.properties 625 | get_strings quest/q090.dat/q090_105d4edd_scp.bin q090_105d4edd_scp.properties 626 | get_strings quest/q091.dat/q091_2f2a0eea_scp.bin q091_2f2a0eea_scp.properties 627 | get_strings quest/q092.dat/q092_82c2e878_scp.bin q092_82c2e878_scp.properties 628 | get_strings ph4/p400.dat/p400_1afc5db6_scp.bin p400_1afc5db6_scp.properties 629 | get_strings ph4/p400.dat/p400_5489214b_scp.bin p400_5489214b_scp.properties 630 | get_strings novel/M1030_S0310_N${LANG3}.txt M1030_S0310_N${LANG3}.txt 631 | get_strings novel/M1070_S0020_N${LANG3}.txt M1070_S0020_N${LANG3}.txt 632 | get_strings novel/M1070_S0040_N${LANG3}.txt M1070_S0040_N${LANG3}.txt 633 | get_strings novel/M1070_S0060_N${LANG3}.txt M1070_S0060_N${LANG3}.txt 634 | get_strings novel/M1070_S0080_N${LANG3}.txt M1070_S0080_N${LANG3}.txt 635 | get_strings novel/M1070_S0100_N${LANG3}.txt M1070_S0100_N${LANG3}.txt 636 | get_strings novel/M3060_S0005_N${LANG3}.txt M3060_S0005_N${LANG3}.txt 637 | get_strings novel/M3060_S0035_GM_N${LANG3}.txt M3060_S0035_GM_N${LANG3}.txt 638 | get_strings novel/M3060_S0910_N${LANG3}.txt M3060_S0910_N${LANG3}.txt 639 | get_strings novel/M6010_S0050_N${LANG3}.txt M6010_S0050_N${LANG3}.txt 640 | get_strings novel/M6010_S0150_N${LANG3}.txt M6010_S0150_N${LANG3}.txt 641 | get_strings novel/M6010_S0250_N${LANG3}.txt M6010_S0250_N${LANG3}.txt 642 | get_strings novel/M9000_S0500_N${LANG3}.txt M9000_S0500_N${LANG3}.txt 643 | #get_strings novel/M3060_S0035_GM_N_Sample_0912_eng.txt M3060_S0035_GM_N_Sample_0912_eng.txt 644 | get_strings novel/M5095_S0020_N${LANG3}.txt M5095_S0020_N${LANG3}.txt 645 | get_strings novel/M5095_S0025_N${LANG3}.txt M5095_S0025_N${LANG3}.txt 646 | get_strings novel/M5095_S0100_N${LANG3}.txt M5095_S0100_N${LANG3}.txt 647 | get_strings novel/M5095_S0200_N${LANG3}.txt M5095_S0200_N${LANG3}.txt 648 | get_strings novel/M5095_S0300_N${LANG3}.txt M5095_S0300_N${LANG3}.txt 649 | -------------------------------------------------------------------------------- /omegat/files_order.txt: -------------------------------------------------------------------------------- 1 | core_hap.properties 2 | messloading.properties 3 | messtitle.properties 4 | messoption.properties 5 | messcore_pc.properties 6 | messcore.properties 7 | messcore_2.properties 8 | txt_core.properties 9 | txt_core_add.properties 10 | messpause.properties 11 | txt_pause.properties 12 | txt_pause_add.properties 13 | messshop.properties 14 | txt_shop.properties 15 | messhud.properties 16 | messhud_hacking.properties 17 | txt_hud.properties 18 | txt_hud_add.properties 19 | messevent.properties 20 | messcredit.properties 21 | txt_credit.properties 22 | messdbg.properties 23 | messchapter.properties 24 | txt_chapter.properties 25 | messending.properties 26 | txt_support.properties 27 | messdlc1.properties 28 | messdlc2.properties 29 | messdlc3.properties 30 | txt_dlc1.properties 31 | txt_dlc2.properties 32 | txt_dlc3.properties 33 | messending_dlc.properties 34 | p100_fa238e7c_scp.properties 35 | p100_c6ab1d8f_scp.properties 36 | subtitle0010.properties 37 | subtitle0011.properties 38 | subtitle0030.properties 39 | subtitle0031.properties 40 | p100_dfcc155d_scp.properties 41 | p100_7f31f924_scp.properties 42 | subtitle0040.properties 43 | p100_d8a4a747_scp.properties 44 | p100_e1dc4db4_scp.properties 45 | p100_e2d39d13_scp.properties 46 | subtitle0055.properties 47 | subtitle0060.properties 48 | subtitleb060.properties 49 | p100_440fda42_scp.properties 50 | p100_536bd4fb_scp.properties 51 | p100_7c282dc8_scp.properties 52 | r120_f0d26b5d_scp.properties 53 | p100_cbfd7706_scp.properties 54 | p100_6a34d49e_scp.properties 55 | p100_301b50d3_scp.properties 56 | p100_5f2b7c58_scp.properties 57 | p100_a85f65ec_scp.properties 58 | subtitle0080.properties 59 | subtitle0081.properties 60 | p100_10a1b8c_scp.properties 61 | subtitle0086.properties 62 | p100_8371cfcf_scp.properties 63 | subtitle0090.properties 64 | subtitle0091.properties 65 | subtitle0092.properties 66 | p100_54edd5c_scp.properties 67 | subtitle0110.properties 68 | subtitle0111.properties 69 | qac8_fd8ac7ea_scp.properties 70 | qaf4_e04e13b1_scp.properties 71 | subtitle0120.properties 72 | p100_ce928ad9_scp.properties 73 | p100_89910ddf_scp.properties 74 | subtitle0130.properties 75 | p100_a5817204_scp.properties 76 | subtitle0140.properties 77 | p100_6695192d_scp.properties 78 | subtitle0160.properties 79 | subtitle0050.properties 80 | subtitle0170.properties 81 | p100_4aa7dace_scp.properties 82 | p100_43f203b8_scp.properties 83 | p100_90998b13_scp.properties 84 | subtitle0190.properties 85 | subtitle0191.properties 86 | subtitleb191.properties 87 | p100_973474b4_scp.properties 88 | p100_69ab2de6_scp.properties 89 | p100_643b9449_scp.properties 90 | p100_306867fd_scp.properties 91 | p100_61b598fd_scp.properties 92 | r150_5ced6cf8_scp.properties 93 | subtitle0225.properties 94 | subtitle0226.properties 95 | p100_39cda07a_scp.properties 96 | p100_9092a1f1_scp.properties 97 | subtitle0240.properties 98 | subtitle0241.properties 99 | subtitle0230.properties 100 | p100_1a401b0f_scp.properties 101 | p100_ec82f9bf_scp.properties 102 | subtitle0250.properties 103 | subtitle0251.properties 104 | subtitleb251.properties 105 | p100_cb2621f3_scp.properties 106 | subtitle0260.properties 107 | subtitle0262.properties 108 | p100_56f39801_scp.properties 109 | p100_6fc2accc_scp.properties 110 | p100_824dfa10_scp.properties 111 | p100_508c029e_scp.properties 112 | p100_a2a7da53_scp.properties 113 | subtitle0270.properties 114 | subtitle0280.properties 115 | p100_23622eee_scp.properties 116 | r130_e5cfdb23_scp.properties 117 | p100_56e518db_scp.properties 118 | subtitle0300.properties 119 | subtitle0301.properties 120 | subtitleb301.properties 121 | p100_2299a056_scp.properties 122 | qab2_aec178b7_scp.properties 123 | subtitle0310.properties 124 | subtitle0311.properties 125 | subtitleb311.properties 126 | qab3_934fd3b1_scp.properties 127 | subtitle0320.properties 128 | subtitle0321.properties 129 | subtitle0322.properties 130 | subtitle0323.properties 131 | subtitleb321.properties 132 | p100_73ce9cac_scp.properties 133 | p100_adc09aec_scp.properties 134 | p100_81c8f672_scp.properties 135 | p200_a2a7da53_scp.properties 136 | subtitle0325.properties 137 | subtitle0326.properties 138 | p100_47a5d6eb_scp.properties 139 | r140_29cb90b_scp.properties 140 | r140_60377331_scp.properties 141 | r140_82d2caac_scp.properties 142 | r140_cd4fd96a_scp.properties 143 | r140_f82d8b66_scp.properties 144 | p100_9b15340d_scp.properties 145 | r100_c723351a_scp.properties 146 | subtitle0330.properties 147 | p200_2e8bdcb0_scp.properties 148 | p200_886c2178_scp.properties 149 | p200_92dddd6e_scp.properties 150 | subtitle0340.properties 151 | subtitle0341.properties 152 | subtitleb341.properties 153 | p200_bb51fdfc_scp.properties 154 | subtitle0350.properties 155 | subtitle0351.properties 156 | subtitle0352.properties 157 | subtitleb351.properties 158 | subtitle0360.properties 159 | p200_b99094bd_scp.properties 160 | p200_20084f1f_scp.properties 161 | p200_a3d6d2f5_scp.properties 162 | p200_7c0c6f18_scp.properties 163 | p200_c544d6ad_scp.properties 164 | p200_78334de1_scp.properties 165 | subtitle0370.properties 166 | p200_24125524_scp.properties 167 | p200_7398bbfd_scp.properties 168 | p200_24194e13_scp.properties 169 | p200_647d1cd7_scp.properties 170 | p200_3c562f91_scp.properties 171 | p200_ff3d446f_scp.properties 172 | p200_d0b71b3b_scp.properties 173 | r160_3fa0647a_scp.properties 174 | r160_74d9b777_scp.properties 175 | r160_1557ce81_scp.properties 176 | p200_71c59d9f_scp.properties 177 | p200_8cbb3f1e_scp.properties 178 | r160_7247f0a7_scp.properties 179 | p200_2bfce9ed_scp.properties 180 | p200_48a7f0fd_scp.properties 181 | r160_307c8a44_scp.properties 182 | r160_f8f21cd2_scp.properties 183 | subtitle0390.properties 184 | subtitle0400.properties 185 | subtitle0410.properties 186 | p200_6ae550e0_scp.properties 187 | p200_96e13a06_scp.properties 188 | p200_ad4026af_scp.properties 189 | p200_8182a35a_scp.properties 190 | p200_27db07bb_scp.properties 191 | subtitle0440.properties 192 | subtitle0441.properties 193 | subtitleb441.properties 194 | p200_20cd934d_scp.properties 195 | p200_5dfcaace_scp.properties 196 | p200_e723b449_scp.properties 197 | p200_a1e11071_scp.properties 198 | p200_e8fce7cc_scp.properties 199 | subtitle0460.properties 200 | subtitle0461.properties 201 | subtitleb461.properties 202 | p200_4b245f40_scp.properties 203 | subtitle0470.properties 204 | subtitle0471.properties 205 | subtitleb471.properties 206 | p200_c7ba8911_scp.properties 207 | p200_f764463b_scp.properties 208 | p200_a68c4ea9_scp.properties 209 | subtitle0475.properties 210 | p200_e8cf2a5c_scp.properties 211 | subtitle0485.properties 212 | subtitle0420.properties 213 | subtitle0482.properties 214 | subtitle0483.properties 215 | subtitle0490.properties 216 | subtitle0491.properties 217 | p200_58623dde_scp.properties 218 | p200_d5ac1e7d_scp.properties 219 | subtitle0500.properties 220 | qab5_4a1ea1bc_scp.properties 221 | subtitle0520.properties 222 | subtitle0521.properties 223 | p200_1cc100aa_scp.properties 224 | subtitle0525.properties 225 | subtitle0526.properties 226 | subtitle0530.properties 227 | subtitle0531.properties 228 | subtitle0540.properties 229 | subtitle0550.properties 230 | subtitle0552.properties 231 | subtitle0502.properties 232 | qab6_69325679_scp.properties 233 | p200_398cde2c_scp.properties 234 | p200_f1f22ca2_scp.properties 235 | p200_aad478cc_scp.properties 236 | p200_7914bf_scp.properties 237 | subtitle0570.properties 238 | subtitle0571.properties 239 | p200_c44b75b3_scp.properties 240 | p200_b4fc12d6_scp.properties 241 | p200_1fcb850d_scp.properties 242 | p200_67909aeb_scp.properties 243 | p200_8806bcb7_scp.properties 244 | p200_7793b6d6_scp.properties 245 | qaba_a7ed1850_scp.properties 246 | p200_17d05835_scp.properties 247 | qabb_1e5a233e_scp.properties 248 | p200_99454795_scp.properties 249 | p200_56645a4b_scp.properties 250 | p200_9a8a8724_scp.properties 251 | subtitle0590.properties 252 | p200_8767f81e_scp.properties 253 | subtitle0600.properties 254 | subtitle0610.properties 255 | subtitle0612.properties 256 | p200_40b3c93d_scp.properties 257 | p200_c3ab84c7_scp.properties 258 | p200_d0a7f4dc_scp.properties 259 | subtitle0630.properties 260 | subtitle0631.properties 261 | p200_cc694d55_scp.properties 262 | p200_7a5876f7_scp.properties 263 | p200_d75fa9d2_scp.properties 264 | subtitle0640.properties 265 | subtitle0650.properties 266 | subtitle0651.properties 267 | subtitleb651.properties 268 | p200_dad50fa7_scp.properties 269 | subtitle0655.properties 270 | subtitle0656.properties 271 | subtitleb656.properties 272 | p200_9dd3606e_scp.properties 273 | p200_6aa3f28e_scp.properties 274 | subtitle0660.properties 275 | subtitle0661.properties 276 | subtitleb661.properties 277 | p200_2311697b_scp.properties 278 | p200_1de99b24_scp.properties 279 | qabd_18ca8961_scp.properties 280 | p200_3456f87_scp.properties 281 | p200_8118914c_scp.properties 282 | subtitle0670.properties 283 | subtitle0671.properties 284 | subtitleb671.properties 285 | p200_5a63902e_scp.properties 286 | subtitle0680.properties 287 | subtitle0682.properties 288 | p200_2fb68036_scp.properties 289 | subtitle0690.properties 290 | subtitle0692.properties 291 | subtitle0700.properties 292 | subtitle0702.properties 293 | p300_f80fe22d_scp.properties 294 | subtitle0642.properties 295 | subtitle0693.properties 296 | subtitle0694.properties 297 | subtitle0720.properties 298 | subtitle0722.properties 299 | subtitle0730.properties 300 | p300_abb1d768_scp.properties 301 | p300_69ab2de6_scp.properties 302 | p300_fe415e44_scp.properties 303 | p300_e9106cc6_scp.properties 304 | subtitle0760.properties 305 | subtitle0761.properties 306 | subtitle0770.properties 307 | subtitle0771.properties 308 | subtitle0780.properties 309 | subtitle0781.properties 310 | qad0_c493efec_scp.properties 311 | p300_a60ff1fc_scp.properties 312 | subtitle0790.properties 313 | subtitle0791.properties 314 | subtitle0792.properties 315 | p300_d578eca9_scp.properties 316 | subtitle0800.properties 317 | subtitle0810.properties 318 | subtitle0811.properties 319 | p300_26ad4903_scp.properties 320 | subtitle0820.properties 321 | subtitle0830.properties 322 | p300_8352dd61_scp.properties 323 | subtitle0835.properties 324 | subtitle0836.properties 325 | p300_1cc46857_scp.properties 326 | p300_a34d9d8a_scp.properties 327 | subtitle0850.properties 328 | p300_2ac25a34_scp.properties 329 | subtitle0855.properties 330 | p300_e47baab_scp.properties 331 | p300_73ee82d4_scp.properties 332 | subtitle0860.properties 333 | subtitle0861.properties 334 | p300_1c94bbb3_scp.properties 335 | p300_969b4cd4_scp.properties 336 | p300_52095a27_scp.properties 337 | r140_657c1219_scp.properties 338 | p300_5f56e621_scp.properties 339 | subtitle0870.properties 340 | subtitle0871.properties 341 | p300_d7fb6a72_scp.properties 342 | subtitle0875.properties 343 | qad1_55fcb9b3_scp.properties 344 | subtitle0880.properties 345 | p300_a80afa1d_scp.properties 346 | subtitle0900.properties 347 | subtitle0901.properties 348 | p300_58e3f469_scp.properties 349 | p300_b863f435_scp.properties 350 | qb20_42c8efa_scp.properties 351 | qb20_91cf1fa5_scp.properties 352 | r200_427ea0a7_scp.properties 353 | p300_4ac43a7f_scp.properties 354 | p300_f29af5ee_scp.properties 355 | subtitle0910.properties 356 | p300_59a32047_scp.properties 357 | p300_ebb2aa60_scp.properties 358 | subtitle0920.properties 359 | subtitle0921.properties 360 | subtitle0926.properties 361 | subtitle0930.properties 362 | subtitle0931.properties 363 | p300_2b0332c8_scp.properties 364 | p300_8f18b72c_scp.properties 365 | subtitle0940.properties 366 | p300_78ebd792_scp.properties 367 | p300_4fce2323_scp.properties 368 | subtitle0950.properties 369 | subtitle0951.properties 370 | p300_abb0feab_scp.properties 371 | p300_7677d46d_scp.properties 372 | p300_33eec348_scp.properties 373 | p300_312ca323_scp.properties 374 | global_d595bcd1_scp.properties 375 | p300_b01535dd_scp.properties 376 | subtitle0935.properties 377 | subtitle0936.properties 378 | subtitle0960.properties 379 | subtitle0961.properties 380 | p300_6f88066d_scp.properties 381 | p300_454d3c27_scp.properties 382 | subtitle0970.properties 383 | qad2_e6ef8eaf_scp.properties 384 | r140_7e0bd84f_scp.properties 385 | p300_fb6b9581_scp.properties 386 | subtitle0990.properties 387 | p300_838131a5_scp.properties 388 | subtitle1000.properties 389 | subtitle1001.properties 390 | subtitle1010.properties 391 | p300_540e0da_scp.properties 392 | p300_e3d05ab7_scp.properties 393 | p300_dd8b37bd_scp.properties 394 | p300_9d8df164_scp.properties 395 | p300_af5fb37c_scp.properties 396 | p300_d48627b4_scp.properties 397 | subtitle1030.properties 398 | p300_34ffac43_scp.properties 399 | p300_2460bab4_scp.properties 400 | subtitle1040.properties 401 | subtitle1041.properties 402 | p300_fe580523_scp.properties 403 | subtitle1050.properties 404 | subtitle1051.properties 405 | p300_be18477d_scp.properties 406 | subtitle1060.properties 407 | p300_7220e53d_scp.properties 408 | p300_79a7d0d0_scp.properties 409 | subtitle1080.properties 410 | subtitle1090.properties 411 | subtitle1091.properties 412 | p300_cc42e29e_scp.properties 413 | qad6_b6255483_scp.properties 414 | p300_d86d80b1_scp.properties 415 | subtitle1100.properties 416 | p300_fb5ab100_scp.properties 417 | p300_62973173_scp.properties 418 | subtitle1120.properties 419 | subtitle1121.properties 420 | p300_249dcf6a_scp.properties 421 | p300_f0e6bd59_scp.properties 422 | p300_95a183ba_scp.properties 423 | p300_24fd47f4_scp.properties 424 | subtitle1150.properties 425 | subtitle1160.properties 426 | p300_50eb25b8_scp.properties 427 | p300_ac91bbe4_scp.properties 428 | p300_d913dcc1_scp.properties 429 | subtitle1180.properties 430 | subtitle1181.properties 431 | p300_df90c81a_scp.properties 432 | p300_54b1765c_scp.properties 433 | p300_9b77492c_scp.properties 434 | qaeb_98b8e891_scp.properties 435 | subtitle1190.properties 436 | subtitle1191.properties 437 | p300_4a0a3acc_scp.properties 438 | p300_157c0c19_scp.properties 439 | subtitle1210.properties 440 | subtitle1211.properties 441 | p300_802d17e9_scp.properties 442 | p300_fca61b8d_scp.properties 443 | subtitle1220.properties 444 | subtitle1221.properties 445 | p300_544f9315_scp.properties 446 | subtitle1230.properties 447 | p300_987be645_scp.properties 448 | subtitle1232.properties 449 | subtitle1233.properties 450 | subtitle1234.properties 451 | subtitle1235.properties 452 | p300_68b9c234_scp.properties 453 | subtitle1240.properties 454 | subtitle1241.properties 455 | p300_10112854_scp.properties 456 | qaef_10112854_scp.properties 457 | subtitle1250.properties 458 | subtitle1260.properties 459 | p300_d2ca712b_scp.properties 460 | pf31_d2ca712b_scp.properties 461 | subtitle1270.properties 462 | p300_7de5c329_scp.properties 463 | pf10_7de5c329_scp.properties 464 | r110_be7ebe38_scp.properties 465 | r200_d52e3bf5_scp.properties 466 | p400_b0e38442_scp.properties 467 | pf30_148bec7a_scp.properties 468 | q020_404eba3d_scp.properties 469 | q031_b551328a_scp.properties 470 | q032_94bdfeb7_scp.properties 471 | r200_e684ee2d_scp.properties 472 | q040_cf7c14d9_scp.properties 473 | r140_9fbdc6a2_scp.properties 474 | r140_dc76121c_scp.properties 475 | q070_fb360535_scp.properties 476 | q071_1a17171a_scp.properties 477 | r160_19656865_scp.properties 478 | r160_e290faf0_scp.properties 479 | r170_e7cef294_scp.properties 480 | r150_f100866e_scp.properties 481 | q080_64afc72a_scp.properties 482 | q090_11b12a94_scp.properties 483 | q090_86062922_scp.properties 484 | subtitle1290.properties 485 | q091_def6c866_scp.properties 486 | q091_402dfd2e_scp.properties 487 | q091_e03615dd_scp.properties 488 | subtitle1300.properties 489 | q092_3cd7f934_scp.properties 490 | q092_35330df_scp.properties 491 | subtitle1310.properties 492 | q095_fc4d3b85_scp.properties 493 | p400_fc21ced3_scp.properties 494 | p400_3af366c3_scp.properties 495 | qc50_de375136_scp.properties 496 | p400_5b4661f4_scp.properties 497 | p400_42374ea5_scp.properties 498 | pf60_149e7cbe_scp.properties 499 | subtitle1320.properties 500 | q100_f4f7e973_scp.properties 501 | q101_5be5b4cc_scp.properties 502 | q102_28e223f7_scp.properties 503 | q103_d2b3f5a6_scp.properties 504 | q104_e9ff21ee_scp.properties 505 | q110_171236f0_scp.properties 506 | r140_ea0da2aa_scp.properties 507 | q120_8dcd7a1a_scp.properties 508 | q121_70545c1f_scp.properties 509 | r110_6b1cbecb_scp.properties 510 | q122_3a5128c8_scp.properties 511 | q123_6fde04e_scp.properties 512 | q130_b68bfe22_scp.properties 513 | qc30_fde14379_scp.properties 514 | q140_7cda31e_scp.properties 515 | q150_d31e5833_scp.properties 516 | q160_d8b9d0be_scp.properties 517 | q162_fc7da4a2_scp.properties 518 | q170_96333b78_scp.properties 519 | q171_12f2963a_scp.properties 520 | q181_746d944f_scp.properties 521 | q180_2d2126d2_scp.properties 522 | q210_a6306d6c_scp.properties 523 | r200_c832af28_scp.properties 524 | q220_e880784a_scp.properties 525 | q221_b113244a_scp.properties 526 | q222_f8217e42_scp.properties 527 | p300_f4f38872_scp.properties 528 | g11516_2ccba2ea_scp.properties 529 | r140_336c5af9_scp.properties 530 | q290_e15f2fa1_scp.properties 531 | r530_3c8107d_scp.properties 532 | q300_5f9ed04e_scp.properties 533 | q330_21f485e_scp.properties 534 | q330_70a701da_scp.properties 535 | q330_9bafd382_scp.properties 536 | q330_b853020f_scp.properties 537 | q330_ee317264_scp.properties 538 | subtitle1280.properties 539 | q340_5620eb59_scp.properties 540 | q360_8efed5ef_scp.properties 541 | qc10_ea55109b_scp.properties 542 | qc11_e05e7f97_scp.properties 543 | qc12_9b9e9b86_scp.properties 544 | q400_1f6199eb_scp.properties 545 | q400_21ca35cb_scp.properties 546 | q400_48d76c20_scp.properties 547 | q400_fc5b48ad_scp.properties 548 | q401_643e5418_scp.properties 549 | q403_5d43ba8b_scp.properties 550 | q410_4f2b901a_scp.properties 551 | q440_3b4ef61d_scp.properties 552 | r160_dc20cee5_scp.properties 553 | q500_8446c06e_scp.properties 554 | r130_12b5a85a_scp.properties 555 | q520_afd5aa67_scp.properties 556 | q532_65ff89bf_scp.properties 557 | q540_e1207097_scp.properties 558 | q550_688e8050_scp.properties 559 | q560_291dbe71_scp.properties 560 | q561_74b9a716_scp.properties 561 | q562_e10ec9ab_scp.properties 562 | r110_4ebc3b22_scp.properties 563 | q590_13ffe891_scp.properties 564 | q720_bbe0d32e_scp.properties 565 | q640_ccd60068_scp.properties 566 | q650_96497077_scp.properties 567 | q651_87a1f20b_scp.properties 568 | q652_4e20ab43_scp.properties 569 | global_60efb803_scp.properties 570 | q660_f737718_scp.properties 571 | q680_51d704e4_scp.properties 572 | r200_d4dad831_scp.properties 573 | q770_59f68d25_scp.properties 574 | q800_bc7a2755_scp.properties 575 | q801_6c8f629a_scp.properties 576 | r140_49e73635_scp.properties 577 | q900_626a2689_scp.properties 578 | q910_8d8ebfae_scp.properties 579 | p300_4716685f_scp.properties 580 | p300_e6cf440a_scp.properties 581 | p100_264b174c_scp.properties 582 | q920_e5072c9_scp.properties 583 | r170_261956fa_scp.properties 584 | r150_df579346_scp.properties 585 | global_638e40c8_scp.properties 586 | subtitle1400.properties 587 | subtitle1402.properties 588 | qb40_f2a5ded9_scp.properties 589 | qb40_b490bdc_scp.properties 590 | r110_7fe2a715_scp.properties 591 | qb40_ff6d92e9_scp.properties 592 | qb40_9403a9bc_scp.properties 593 | p300_22633b31_scp.properties 594 | p300_ae2eada6_scp.properties 595 | p300_d2de713_scp.properties 596 | p300_c0c1e86c_scp.properties 597 | p300_e4c7a829_scp.properties 598 | qb40_f7708d83_scp.properties 599 | r160_441c44e3_scp.properties 600 | r160_7cde1b3f_scp.properties 601 | r110_7a562cb9_scp.properties 602 | r110_dd7422a2_scp.properties 603 | q090_105d4edd_scp.properties 604 | q091_2f2a0eea_scp.properties 605 | q092_82c2e878_scp.properties 606 | p400_1afc5db6_scp.properties 607 | p400_5489214b_scp.properties 608 | M1030_S0310_N_eng.txt 609 | M1070_S0020_N_eng.txt 610 | M1070_S0040_N_eng.txt 611 | M1070_S0060_N_eng.txt 612 | M1070_S0080_N_eng.txt 613 | M1070_S0100_N_eng.txt 614 | M3060_S0005_N_eng.txt 615 | M3060_S0035_GM_N_eng.txt 616 | M3060_S0910_N_eng.txt 617 | M6010_S0050_N_eng.txt 618 | M6010_S0150_N_eng.txt 619 | M6010_S0250_N_eng.txt 620 | M9000_S0500_N_eng.txt 621 | M3060_S0035_GM_N_Sample_0912_eng.txt 622 | M5095_S0020_N_eng.txt 623 | M5095_S0025_N_eng.txt 624 | M5095_S0100_N_eng.txt 625 | M5095_S0200_N_eng.txt 626 | M5095_S0300_N_eng.txt 627 | -------------------------------------------------------------------------------- /prepare.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Unpacking dat files" 4 | ./tools/unpack_dat.py data unpacked 5 | 6 | astcenc_tool=./tools/astcenc-avx2 7 | if [[ $OSTYPE == 'cygwin' || $OSTYPE == 'msys' ]] 8 | then astcenc_tool=./tools/astcenc-avx2.exe 9 | fi 10 | 11 | for astc_file in `find unpacked/ -name '*.astc'` 12 | do 13 | dds_file=${astc_file:0:-5} 14 | ${astcenc_tool} -dl ${astc_file} ${dds_file} 15 | done 16 | 17 | ./prepare_fonts.sh 18 | 19 | ./get_strings.sh 20 | -------------------------------------------------------------------------------- /prepare_fonts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Extracting fonts - it will take several minutes" 4 | echo "Extracting fonts from ftb files" 5 | for font in 00 01 04 05 11 6 | do 7 | ftb=unpacked/font/font_${font}.dat/font_${font}.ftb 8 | textures=unpacked/font/font_${font}.dtt/font_${font}.wtp_*.dds 9 | out_dir=fonts/${font} 10 | ./tools/unpack_font.py --skip-cjk ${ftb} ${out_dir} ${textures} 11 | done 12 | 13 | function extract_mcd() { 14 | mcd=$1 15 | font=$2 16 | echo "Extracting font ${font} from ${mcd}" 17 | texture=`echo $mcd | sed -e 's/\.dat/.dtt/' -e 's/\.mcd/.wtp_000.dds/'` 18 | out_dir=fonts/${font} 19 | ./tools/unpack_font.py --font-id ${font} --skip-cjk ${mcd} ${out_dir} ${texture} 20 | } 21 | 22 | function extract_mcd_with_cjk() { 23 | mcd=$1 24 | font=$2 25 | echo "Extracting font ${font} from ${mcd}" 26 | texture=`echo $mcd | sed -e 's/\.dat/.dtt/' -e 's/\.mcd/.wtp_000.dds/'` 27 | out_dir=fonts/${font} 28 | ./tools/unpack_font.py --font-id ${font} ${mcd} ${out_dir} ${texture} 29 | } 30 | 31 | for lang in "" "_us" "_fr" "_it" "_de" "_es" 32 | do 33 | extract_mcd unpacked/ui/ui_title${lang}.dat/messtitle.mcd 02 34 | extract_mcd unpacked/ui/ui_core${lang}.dat/messcore.mcd 02 35 | extract_mcd unpacked/ui/ui_shop${lang}.dat/messshop.mcd 02 36 | extract_mcd unpacked/ui/ui_hud${lang}.dat/messhud.mcd 02 37 | extract_mcd unpacked/ui/ui_hud_hacking${lang}.dat/messhud_hacking.mcd 02 38 | extract_mcd unpacked/ui/ui_chapter${lang}.dat/messchapter.mcd 02 39 | extract_mcd unpacked/ui/ui_ending${lang}.dat/messending.mcd 02 40 | extract_mcd unpacked/ui/ui_dlc1${lang}.dat/messdlc1.mcd 02 41 | extract_mcd unpacked/ui/ui_option${lang}.dat/messoption.mcd 02 42 | extract_mcd unpacked/ui/ui_core${lang}.dat/messcore.mcd 03 43 | extract_mcd unpacked/ui/ui_dlc1${lang}.dat/messdlc1.mcd 03 44 | extract_mcd unpacked/ui/ui_ending${lang}.dat/messending.mcd 03 45 | extract_mcd unpacked/ui/ui_pause${lang}.dat/messpause.mcd 08 46 | extract_mcd unpacked/ui/ui_core${lang}.dat/messcore.mcd 09 47 | extract_mcd unpacked/ui/ui_core_2${lang}.dat/messcore_2.mcd 09 48 | extract_mcd unpacked/ui/ui_dbg${lang}.dat/messdbg.mcd 10 49 | done 50 | extract_mcd_with_cjk unpacked/ui/ui_loading.dat/messloading.mcd 01 51 | extract_mcd_with_cjk unpacked/ui/ui_loading.dat/messloading.mcd 02 52 | extract_mcd_with_cjk unpacked/ui/ui_loading.dat/messloading.mcd 05 53 | ./tools/unpack_font.py --char $((16#2514)) --font-id 36 unpacked/ui/ui_chapter_us.dat/messchapter.mcd fonts/01 unpacked/ui/ui_chapter_us.dtt/messchapter.wtp_000.dds 54 | ./tools/unpack_font.py --char $((16#251c)) --font-id 36 unpacked/ui/ui_chapter_us.dat/messchapter.mcd fonts/01 unpacked/ui/ui_chapter_us.dtt/messchapter.wtp_000.dds 55 | 56 | ./tools/unpack_font.py --char $((16#300a)) --font-id 36 unpacked/ui/ui_core_us.dat/messcore.mcd fonts/01 unpacked/ui/ui_core_us.dtt/messcore.wtp_000.dds 57 | ./tools/unpack_font.py --char $((16#300b)) --font-id 36 unpacked/ui/ui_core_us.dat/messcore.mcd fonts/01 unpacked/ui/ui_core_us.dtt/messcore.wtp_000.dds 58 | ./tools/unpack_font.py --char $((16#300e)) --font-id 36 unpacked/ui/ui_core_us.dat/messcore.mcd fonts/01 unpacked/ui/ui_core_us.dtt/messcore.wtp_000.dds 59 | ./tools/unpack_font.py --char $((16#300f)) --font-id 36 unpacked/ui/ui_core_us.dat/messcore.mcd fonts/01 unpacked/ui/ui_core_us.dtt/messcore.wtp_000.dds 60 | 61 | ./tools/unpack_font.py --char $((16#65e5)) --font-id 1 unpacked/ui/ui_option_us.dat/messoption.mcd fonts/01 unpacked/ui/ui_option_us.dtt/messoption.wtp_000.dds 62 | ./tools/unpack_font.py --char $((16#672c)) --font-id 1 unpacked/ui/ui_option_us.dat/messoption.mcd fonts/01 unpacked/ui/ui_option_us.dtt/messoption.wtp_000.dds 63 | ./tools/unpack_font.py --char $((16#8a9e)) --font-id 1 unpacked/ui/ui_option_us.dat/messoption.mcd fonts/01 unpacked/ui/ui_option_us.dtt/messoption.wtp_000.dds 64 | 65 | -------------------------------------------------------------------------------- /tools/astcenc-avx2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synspawacza/nier_automata_localization/913826bcd6bec4cd320cfe4ce2e6f1305e024439/tools/astcenc-avx2 -------------------------------------------------------------------------------- /tools/astcenc-avx2.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/synspawacza/nier_automata_localization/913826bcd6bec4cd320cfe4ce2e6f1305e024439/tools/astcenc-avx2.exe -------------------------------------------------------------------------------- /tools/clone_kernings.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import argparse 4 | import format.ktb as ktb 5 | from PIL import Image 6 | 7 | if __name__ == "__main__": 8 | parser = argparse.ArgumentParser() 9 | parser.add_argument("input", help="source kerning table file") 10 | parser.add_argument("output", help="target kerning table file") 11 | parser.add_argument( 12 | "--chars", 13 | help="character id to clone", 14 | metavar=("FROM", "TO"), 15 | nargs=2, 16 | action="append", 17 | ) 18 | 19 | args = parser.parse_args() 20 | 21 | kerning_table = None 22 | with open(args.input, "rb") as input_ktb: 23 | kerning_table = ktb.File.parse(input_ktb) 24 | 25 | chars = [(chr(int(c1)), chr(int(c2))) for c1, c2 in args.chars] 26 | 27 | for from_char, to_char in chars: 28 | kerning_table.clone_kerning(from_char, to_char) 29 | with open(args.output, "wb") as out_ktb: 30 | out_ktb.write(kerning_table.serialize()) 31 | -------------------------------------------------------------------------------- /tools/convert_texture.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | astcenc_tool=./tools/astcenc-avx2 4 | if [[ $OSTYPE == 'cygwin' || $OSTYPE == 'msys' ]] 5 | then astcenc_tool=./tools/astcenc-avx2.exe 6 | fi 7 | 8 | SRC_FILE=$1 9 | TGT_FILE=$2 10 | 11 | if [[ ${TGT_FILE##*.} == "dds" ]]; then 12 | convert -define dds:mipmaps=0 ${SRC_FILE} ${TGT_FILE} 13 | else 14 | ${astcenc_tool} -cl ${SRC_FILE} ${TGT_FILE} 4x4 -thorough 15 | fi 16 | -------------------------------------------------------------------------------- /tools/format/bin.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | from format.utils import * 4 | 5 | # based on: 6 | # https://github.com/mrubyc/mrubyc/blob/release2.1/doc/bytecode_format.md 7 | # https://github.com/mrubyc/mrubyc/blob/release2.1/doc/opcodes.md 8 | # https://github.com/mruby/mruby/blob/master/src/load.c 9 | 10 | # based on https://github.com/mruby/mruby/blob/master/src/crc.c 11 | def calc_crc(bytes): 12 | CRC_PATTERN = 0x11021 << 8 13 | CARRY_BIT = 0x01000000 14 | work = 0 15 | for byte in bytes: 16 | work |= byte 17 | for i in range(8): # each bit 18 | work <<= 1 19 | if work & CARRY_BIT: 20 | work ^= CRC_PATTERN 21 | return work >> 8 22 | 23 | 24 | def mruby_op_string(index, pool_id): 25 | return (index << 23) | (pool_id << 7) | 0x3D 26 | 27 | 28 | def mruby_opcode(value): 29 | return value & 0x7F 30 | 31 | 32 | def get_bx(value): 33 | return (value >> 7) & 0xFFFF 34 | 35 | 36 | def get_a(value): 37 | return (value >> 23) & 0x1FF 38 | 39 | 40 | def get_b(value): 41 | return (value >> 14) & 0x1FF 42 | 43 | 44 | def get_c(value): 45 | return (value >> 7) & 0x7F 46 | 47 | 48 | OP_SETCONST = 0x12 49 | OP_ARRAY = 0x37 50 | OP_STRING = 0x3D 51 | 52 | 53 | class Header: 54 | @staticmethod 55 | def parse(reader): 56 | result = Header() 57 | result.magic = read_bytes(reader, 4) 58 | assert_magic(result.magic, b"RITE") 59 | result.version = read_utf8(reader, 4) 60 | read_bytes(reader, 2) # ignore crc 61 | result.size = read_be_int(reader, 4) 62 | result.compiler = read_utf8(reader, 8) 63 | return result 64 | 65 | def serialize(self): 66 | result = bytearray() 67 | result += self.magic 68 | result += write_utf8(self.version, 4) 69 | result += bytearray(b"\0" * 6) # CRC + size to be replaced later 70 | result += write_utf8(self.compiler, 8) 71 | return result 72 | 73 | 74 | class PoolRecord: 75 | @staticmethod 76 | def parse(reader): 77 | result = PoolRecord() 78 | result.type = read_bytes(reader, 1) 79 | size = read_be_int(reader, 2) 80 | result.value = read_utf8(reader, size) 81 | return result 82 | 83 | @staticmethod 84 | def from_string(value=""): 85 | result = PoolRecord() 86 | result.type = b"\0" 87 | result.value = value 88 | return result 89 | 90 | def serialize(self): 91 | result = bytearray() 92 | result += self.type 93 | content = write_utf8(self.value, len(self.value)) 94 | result += write_be_int(len(content), 2) 95 | result += content 96 | return result 97 | 98 | 99 | class IrepSegment: 100 | @staticmethod 101 | def parse(reader): 102 | result = IrepSegment() 103 | read_be_int(reader, 4) # size 104 | result.nlocals = read_be_int(reader, 2) 105 | result.nregs = read_be_int(reader, 2) 106 | result.rlen = read_be_int(reader, 2) 107 | 108 | ninstructions = read_be_int(reader, 4) 109 | read_padding(reader, 4) 110 | result.instructions = [] 111 | for i in range(ninstructions): 112 | result.instructions.append(read_be_int(reader, 4)) 113 | 114 | npool = read_be_int(reader, 4) 115 | result.pool = [] 116 | for i in range(npool): 117 | result.pool.append(PoolRecord.parse(reader)) 118 | 119 | nsymbols = read_be_int(reader, 4) 120 | result.symbols = [] 121 | for i in range(nsymbols): 122 | symbol_size = read_be_int(reader, 2) 123 | if symbol_size == 0xFFFF: 124 | result.symbols.append("") # null symbol 125 | else: 126 | result.symbols.append(read_utf8(reader, symbol_size + 1)) 127 | return result 128 | 129 | def serialize(self, offset): 130 | result = bytearray() 131 | 132 | result += b"\0" * 4 # size placeholder 133 | result += write_be_int(self.nlocals, 2) 134 | result += write_be_int(self.nregs, 2) 135 | result += write_be_int(self.rlen, 2) 136 | 137 | result += write_be_int(len(self.instructions), 4) 138 | 139 | padding = write_padding(offset + len(result), 4) 140 | padding_size = len(padding) 141 | result += padding 142 | 143 | for instr in self.instructions: 144 | result += write_be_int(instr, 4) 145 | 146 | result += write_be_int(len(self.pool), 4) 147 | for val in self.pool: 148 | result += val.serialize() 149 | 150 | result += write_be_int(len(self.symbols), 4) 151 | for symbol in self.symbols: 152 | size = len(symbol) 153 | if size == 0: 154 | result += write_be_int(0xFFFF, 2) 155 | else: 156 | result += write_be_int(size, 2) 157 | result += write_utf8(symbol, size + 1) 158 | 159 | # update reported size to match actul size (with some fiddling around padding bytes) 160 | result[0:4] = write_be_int(len(result) + 4 - padding_size, 4) 161 | 162 | return result 163 | 164 | 165 | class IrepSection: 166 | @staticmethod 167 | def parse(reader): 168 | result = IrepSection() 169 | result.type = read_bytes(reader, 4) 170 | size = read_be_int(reader, 4) 171 | endoffset = reader.tell() + size - 8 172 | result.version = read_bytes(reader, 4) 173 | result.segments = [] 174 | while reader.tell() < endoffset: 175 | result.segments.append(IrepSegment.parse(reader)) 176 | return result 177 | 178 | def serialize(self, offset): 179 | result = bytearray() 180 | result += self.type 181 | result += bytearray(b"\0" * 4) # size placeholder 182 | result += self.version 183 | for segment in self.segments: 184 | result += segment.serialize(offset + len(result)) 185 | result[4:8] = write_be_int(len(result), 4) 186 | return result 187 | 188 | 189 | class UnknownSection: 190 | @staticmethod 191 | def parse(reader): 192 | result = UnknownSection() 193 | result.type = read_bytes(reader, 4) 194 | size = read_be_int(reader, 4) 195 | result.content = read_bytes(reader, size - 8) 196 | return result 197 | 198 | def serialize(self, offset): 199 | result = bytearray() 200 | result += self.type 201 | result += bytearray(b"\0" * 4) # size placeholder 202 | result += self.content 203 | result[4:8] = write_be_int(len(result), 4) 204 | return result 205 | 206 | 207 | class File: 208 | @staticmethod 209 | def parse(reader): 210 | result = File() 211 | reader.seek(0) 212 | 213 | result.header = Header.parse(reader) 214 | result.sections = [] 215 | 216 | while reader.tell() < result.header.size: 217 | section_type = peek_bytes(reader, 4) 218 | if section_type == b"IREP": 219 | result.sections.append(IrepSection.parse(reader)) 220 | else: 221 | result.sections.append(UnknownSection.parse(reader)) 222 | 223 | return result 224 | 225 | def serialize(self): 226 | result = bytearray() 227 | result += self.header.serialize() 228 | for section in self.sections: 229 | result += section.serialize(len(result)) 230 | result[10:14] = write_be_int(len(result), 4) 231 | result[8:10] = write_be_int(calc_crc(result[10:]), 2) 232 | return result 233 | 234 | def get_strings(self, lang): 235 | result = dict() 236 | 237 | LANGS = {"jp": 0, "en": 1, "fr": 2, "it": 3, "de": 4, "es": 5, "ko": 6, "zh": 7} 238 | lang_index = LANGS[lang] 239 | 240 | for section in self.sections: 241 | if not isinstance(section, IrepSection): 242 | continue 243 | for segment in section.segments: 244 | for instr_idx, instr in enumerate(segment.instructions): 245 | array_size = 0 246 | if ( 247 | mruby_opcode(instr) == OP_ARRAY 248 | and get_a(instr) == 1 249 | and get_b(instr) == 1 250 | ): 251 | array_size = get_c(instr) 252 | else: 253 | continue 254 | 255 | if lang_index >= array_size: 256 | raise Exception("Language " + lang + " is not found in file") 257 | 258 | symbol_instr = segment.instructions[instr_idx + 1] 259 | assert mruby_opcode(symbol_instr) == OP_SETCONST 260 | symbol = segment.symbols[get_bx(symbol_instr)] 261 | 262 | str_instr = segment.instructions[ 263 | instr_idx - array_size + lang_index 264 | ] 265 | result[symbol] = segment.pool[get_bx(str_instr)].value 266 | 267 | return dict(sorted(result.items())) 268 | 269 | def put_strings(self, mapping, lang): 270 | LANGS = {"jp": 0, "en": 1, "fr": 2, "it": 3, "de": 4, "es": 5} 271 | lang_index = LANGS[lang] 272 | 273 | for section in self.sections: 274 | if not isinstance(section, IrepSection): 275 | continue 276 | for segment in section.segments: 277 | for instr_idx, instr in enumerate(segment.instructions): 278 | array_size = 0 279 | if ( 280 | mruby_opcode(instr) == OP_ARRAY 281 | and get_a(instr) == 1 282 | and get_b(instr) == 1 283 | ): 284 | array_size = get_c(instr) 285 | else: 286 | continue 287 | 288 | symbol_instr = segment.instructions[instr_idx + 1] 289 | assert mruby_opcode(symbol_instr) == OP_SETCONST 290 | symbol = segment.symbols[get_bx(symbol_instr)] 291 | 292 | prev_str_instr = segment.instructions[ 293 | instr_idx - array_size + lang_index 294 | ] 295 | prev_str = segment.pool[get_bx(prev_str_instr)].value 296 | if mapping[symbol] != prev_str: 297 | segment.pool.append(PoolRecord.from_string(mapping[symbol])) 298 | segment.instructions[ 299 | instr_idx - array_size + lang_index 300 | ] = mruby_op_string(2, len(segment.pool) - 1) 301 | -------------------------------------------------------------------------------- /tools/format/charnames.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | from format.utils import * 4 | import math 5 | 6 | 7 | class File: 8 | @staticmethod 9 | def parse(reader): 10 | result = File() 11 | reader.seek(0) 12 | count = read_int(reader, 4) 13 | 14 | offsets = [] 15 | for i in range(count): 16 | id = read_uint(reader, 5) 17 | offset = read_int(reader, 4) 18 | offsets.append((id, offset)) 19 | 20 | result.entries = {} 21 | for id, offset in offsets: 22 | if id not in result.entries: 23 | result.entries[id] = "" 24 | if offset == 0: 25 | continue 26 | reader.seek(offset) 27 | result.entries[id] += read_zero_terminated_utf8(reader) 28 | 29 | return result 30 | 31 | def serialize(self): 32 | strings = [] 33 | for id, value in self.entries.items(): 34 | if value == "": 35 | strings.append((id, b"")) 36 | else: 37 | bytes = write_utf8(value, 0) 38 | for i in range(math.ceil(len(bytes) / 64)): 39 | strings.append((id, bytes[i * 64 : (i + 1) * 64] + b"\0")) 40 | 41 | result = bytearray() 42 | result += write_int(len(strings), 4) 43 | offset = 4 + 9 * len(strings) 44 | for id, value in strings: 45 | result += write_int(id, 5) 46 | if value == b"": 47 | result += write_int(0, 4) 48 | else: 49 | result += write_int(offset, 4) 50 | offset += len(value) 51 | for id, value in strings: 52 | result += value 53 | return result 54 | 55 | def get_strings(self, lang): 56 | result = dict() 57 | 58 | LANGS = { 59 | "jp": "JPN", 60 | "en": "ENG", 61 | "fr": "FRA", 62 | "it": "ITA", 63 | "de": "GER", 64 | "es": "ESP", 65 | } 66 | lang_id = LANGS[lang] 67 | 68 | character_names_table = bytes.fromhex(self.entries[0x1D77583401])[20:].decode( 69 | "utf-8" 70 | ) 71 | for line in character_names_table.split("\n"): 72 | if len(line) <= 2: 73 | pass 74 | elif line[1] != " ": 75 | id = line.strip(" ") 76 | elif line[2:5] == lang_id: 77 | result[id] = line[6:] 78 | return result 79 | 80 | def put_strings(self, lang, mapping): 81 | LANGS = { 82 | "jp": "JPN", 83 | "en": "ENG", 84 | "fr": "FRA", 85 | "it": "ITA", 86 | "de": "GER", 87 | "es": "ESP", 88 | } 89 | lang_id = LANGS[lang] 90 | 91 | character_names_table = bytes.fromhex(self.entries[0x1D77583401])[20:].decode( 92 | "utf-8" 93 | ) 94 | new_lines = [] 95 | for line in character_names_table.split("\n"): 96 | if len(line) <= 2: 97 | pass 98 | elif line[1] != " ": 99 | id = line.strip(" ") 100 | elif line[2:5] == lang_id: 101 | line = line[:6] + mapping[id] 102 | new_lines.append(line) 103 | new_string = "\n".join(new_lines).encode("utf-8").hex() 104 | 105 | self.entries[0x1D77583401] = self.entries[0x1D77583401][:40] + new_string 106 | strlen = len(self.entries[0x1D77583401]) // 2 107 | self.entries[0xF7C0246A01] = "{:#x}".format(strlen) 108 | -------------------------------------------------------------------------------- /tools/format/dat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | from format.utils import * 4 | 5 | # based on https://gist.github.com/Wunkolo/213aa61eb0c874172aec97ebb8ab89c2 6 | # based on https://github.com/xxk-i/DATrepacker/blob/master/dat_utils.py 7 | 8 | 9 | class Header: 10 | HEADER_SIZE = 32 11 | 12 | @staticmethod 13 | def parse(reader): 14 | result = Header() 15 | result.magic = read_bytes(reader, 4) 16 | assert_magic(result.magic, b"DAT\0") 17 | result.file_count = read_int(reader, 4) 18 | result.file_table_offset = read_int(reader, 4) 19 | result.ext_table_offset = read_int(reader, 4) 20 | result.name_table_offset = read_int(reader, 4) 21 | result.size_table_offset = read_int(reader, 4) 22 | result.crc_table_offset = read_int(reader, 4) 23 | result.unknown = read_bytes(reader, 4) 24 | return result 25 | 26 | def serialize(self): 27 | result = bytearray() 28 | result += self.magic 29 | result += write_int(self.file_count, 4) 30 | result += write_int(self.file_table_offset, 4) 31 | result += write_int(self.ext_table_offset, 4) 32 | result += write_int(self.name_table_offset, 4) 33 | result += write_int(self.size_table_offset, 4) 34 | result += write_int(self.crc_table_offset, 4) 35 | result += self.unknown 36 | return result 37 | 38 | 39 | class Entry: 40 | def __init__(self): 41 | self.name = None 42 | self.offset = None 43 | self.size = None 44 | self.bytes = None 45 | 46 | 47 | class File: 48 | @staticmethod 49 | def parse(reader): 50 | result = File() 51 | reader.seek(0) 52 | result.header = Header.parse(reader) 53 | 54 | result.files = [Entry() for i in range(result.header.file_count)] 55 | 56 | reader.seek(result.header.file_table_offset) 57 | for i in range(result.header.file_count): 58 | result.files[i].offset = read_int(reader, 4) 59 | 60 | reader.seek(result.header.size_table_offset) 61 | for i in range(result.header.file_count): 62 | result.files[i].size = read_int(reader, 4) 63 | 64 | reader.seek(result.header.name_table_offset) 65 | filename_len = read_int(reader, 4) 66 | for i in range(result.header.file_count): 67 | result.files[i].name = read_utf8(reader, filename_len) 68 | 69 | reader.seek(result.header.crc_table_offset) 70 | if len(result.files) > 0: 71 | result.crc_table = read_bytes( 72 | reader, result.files[0].offset - result.header.crc_table_offset 73 | ) 74 | else: 75 | result.crc_table = b"" 76 | 77 | for i in range(result.header.file_count): 78 | reader.seek(result.files[i].offset) 79 | result.files[i].bytes = read_bytes(reader, result.files[i].size) 80 | 81 | return result 82 | 83 | def serialize(self): 84 | result = bytearray(b"\0" * Header.HEADER_SIZE) # placeholder 85 | self.header.file_count = len(self.files) 86 | 87 | self.header.file_table_offset = len(result) 88 | result += b"\0" * 4 * self.header.file_count # placeholder 89 | 90 | self.header.ext_table_offset = len(result) 91 | for file in self.files: 92 | result += write_utf8(file.name.split(".")[-1], 4) 93 | 94 | self.header.name_table_offset = len(result) 95 | filename_len = max([len(f.name) for f in self.files]) + 1 96 | result += write_int(filename_len, 4) 97 | for file in self.files: 98 | result += write_utf8(file.name, filename_len) 99 | 100 | result += write_padding(len(result), 4) 101 | 102 | self.header.size_table_offset = len(result) 103 | for file in self.files: 104 | result += write_int(len(file.bytes), 4) 105 | 106 | self.header.crc_table_offset = len(result) 107 | result += self.crc_table # keep the same CRC 108 | 109 | result += write_padding(len(result), 16) 110 | 111 | offset_table = bytearray() 112 | for file in self.files: 113 | file_offset = len(result) 114 | offset_table += write_int(file_offset, 4) 115 | result += file.bytes 116 | result += write_padding(len(result), 16) 117 | 118 | result[0 : Header.HEADER_SIZE] = self.header.serialize() 119 | result[ 120 | self.header.file_table_offset : self.header.file_table_offset 121 | + len(offset_table) 122 | ] = offset_table 123 | 124 | return result 125 | -------------------------------------------------------------------------------- /tools/format/ftb.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | from format.utils import * 4 | 5 | 6 | class Header: 7 | @staticmethod 8 | def parse(reader): 9 | result = Header() 10 | result.magic = read_bytes(reader, 118) 11 | assert_magic(result.magic, b"FTB ") 12 | result.textures_count = read_int(reader, 2) 13 | result.unknown = read_bytes(reader, 2) 14 | result.chars_count = read_int(reader, 2) 15 | result.textures_offset = read_int(reader, 4) 16 | result.chars_offset = read_int(reader, 4) 17 | result.chars_offset2 = read_int(reader, 4) 18 | return result 19 | 20 | def serialize(self): 21 | result = bytearray() 22 | result += self.magic 23 | result += write_int(self.textures_count, 2) 24 | result += self.unknown 25 | result += write_int(self.chars_count, 2) 26 | result += write_int(self.textures_offset, 4) 27 | result += write_int(self.chars_offset, 4) 28 | result += write_int(self.chars_offset, 4) 29 | return result 30 | 31 | 32 | class Character: 33 | @staticmethod 34 | def parse(reader): 35 | result = Character() 36 | result.char = read_utf16(reader, 2) 37 | result.texture_id = read_int(reader, 2) 38 | result.width = read_int(reader, 2) 39 | result.height = read_int(reader, 2) 40 | result.u = read_int(reader, 2) 41 | result.v = read_int(reader, 2) 42 | return result 43 | 44 | def serialize(self): 45 | result = bytearray() 46 | result += write_utf16(self.char, 2) 47 | result += write_int(self.texture_id, 2) 48 | result += write_int(self.width, 2) 49 | result += write_int(self.height, 2) 50 | result += write_int(self.u, 2) 51 | result += write_int(self.v, 2) 52 | return result 53 | 54 | 55 | class File: 56 | @staticmethod 57 | def parse(reader): 58 | result = File() 59 | reader.seek(0) 60 | result.header = Header.parse(reader) 61 | 62 | reader.seek(result.header.textures_offset) 63 | result.textures = read_bytes(reader, result.header.textures_count * 16) 64 | 65 | reader.seek(result.header.chars_offset) 66 | result.chars = [] 67 | for i in range(result.header.chars_count): 68 | result.chars.append(Character.parse(reader)) 69 | return result 70 | 71 | def find_space_for_glyph(self, glyph_size, texture_size, page): 72 | relevant_glyphs = [c for c in self.chars if c.texture_id == page] 73 | w = glyph_size[0] 74 | h = glyph_size[1] 75 | 76 | glyph_x = 0 77 | glyph_y = texture_size[1] 78 | for x in range(0, texture_size[0] - w - 1, 32): 79 | y = max( 80 | [ 81 | c.v + c.height 82 | for c in relevant_glyphs 83 | if x < c.u + c.width and x + w > c.u 84 | ] 85 | ) 86 | if y < glyph_y: 87 | glyph_x = x 88 | glyph_y = y 89 | 90 | if glyph_y <= texture_size[1] - h - 1: 91 | return (glyph_x, glyph_y) 92 | raise Exception("cannot place character") 93 | 94 | def add_character(self, value, texture, width, height, u, v): 95 | char = Character() 96 | char.char = value 97 | char.texture_id = texture 98 | char.width = width - 1 99 | char.height = height - 1 100 | char.u = u 101 | char.v = v 102 | self.chars.append(char) 103 | self.chars.sort(key=lambda c: c.char) 104 | 105 | def get_glyphs(self, textures, font_id=0): # font_id is ignored 106 | result = {} 107 | for c in self.chars: 108 | if c.width == 0 or c.height == 0 or not c.char: 109 | continue 110 | u1 = c.u 111 | u2 = c.u + c.width + 1 112 | v1 = c.v 113 | v2 = c.v + c.height + 1 114 | result[c.char] = textures[c.texture_id].crop((u1, v1, u2, v2)) 115 | return result 116 | 117 | def serialize(self): 118 | result = bytearray() 119 | self.header.chars_count = len(self.chars) 120 | result += self.header.serialize() 121 | result += self.textures 122 | for c in self.chars: 123 | result += c.serialize() 124 | result += b"\0" * 0x88 # padding? 125 | return result 126 | -------------------------------------------------------------------------------- /tools/format/ktb.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | from format.utils import * 4 | 5 | 6 | class File: 7 | @staticmethod 8 | def parse(reader): 9 | result = File() 10 | reader.seek(0) 11 | count = read_int(reader, 2) 12 | 13 | result.entries = {} 14 | for i in range(count): 15 | left = read_utf16(reader, 2) 16 | right = read_utf16(reader, 2) 17 | kerning = read_int(reader, 2) 18 | result.entries[(left, right)] = kerning 19 | return result 20 | 21 | def clone_kerning(self, from_char, to_char): 22 | new_entries = {} 23 | for e in self.entries: 24 | if e[0] == from_char or e[1] == from_char: 25 | left = e[0] if e[0] != from_char else to_char 26 | right = e[1] if e[1] != from_char else to_char 27 | new_entries[(left, right)] = self.entries[e] 28 | self.entries = {**self.entries, **new_entries} 29 | 30 | def get_kerning(self, left, right): 31 | if (left, right) in self.entries: 32 | return self.entries[(left, right)] 33 | else: 34 | return 0 35 | 36 | def serialize(self): 37 | result = bytearray() 38 | result += write_int(len(self.entries), 2) 39 | for key, value in self.entries.items(): 40 | result += write_utf16(key[0], 2) 41 | result += write_utf16(key[1], 2) 42 | result += write_int(value, 2) 43 | return result 44 | -------------------------------------------------------------------------------- /tools/format/mcd.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | from format.utils import * 4 | 5 | # based on https://zenhax.com/viewtopic.php?t=1502&p=8181 6 | # based on https://github.com/Kerilk/bayonetta_tools/blob/master/binary_templates/Bayonetta%202%20mcd%20base.bt 7 | 8 | 9 | class Header: 10 | ENTRY_SIZE = 40 11 | 12 | @staticmethod 13 | def parse(reader): 14 | result = Header() 15 | result.messages_offset = read_int(reader, 4) 16 | result.messages_count = read_int(reader, 4) 17 | result.symbols_offset = read_int(reader, 4) 18 | result.symbols_count = read_int(reader, 4) 19 | result.glyphs_offset = read_int(reader, 4) 20 | result.glyphs_count = read_int(reader, 4) # should be the same as symbols_count 21 | result.fonts_offset = read_int(reader, 4) 22 | result.fonts_count = read_int(reader, 4) 23 | result.events_offset = read_int(reader, 4) 24 | result.events_count = read_int(reader, 4) # should be thesame as messages_count 25 | return result 26 | 27 | def serialize(self): 28 | result = bytearray() 29 | result += write_int(self.messages_offset, 4) 30 | result += write_int(self.messages_count, 4) 31 | result += write_int(self.symbols_offset, 4) 32 | result += write_int(self.symbols_count, 4) 33 | result += write_int(self.glyphs_offset, 4) 34 | result += write_int(self.glyphs_count, 4) 35 | result += write_int(self.fonts_offset, 4) 36 | result += write_int(self.fonts_count, 4) 37 | result += write_int(self.events_offset, 4) 38 | result += write_int(self.events_count, 4) 39 | return result 40 | 41 | 42 | class Symbol: 43 | # interesting anomaly: character \x80 seems to be used as ellipsis character (…) 44 | ENTRY_SIZE = 8 45 | 46 | @staticmethod 47 | def parse(reader): 48 | result = Symbol() 49 | result.font_id = read_int(reader, 2) 50 | result.char = read_utf16(reader, 2) 51 | result.glyph_id = read_int(reader, 4) 52 | return result 53 | 54 | def serialize(self): 55 | result = bytearray() 56 | result += write_int(self.font_id, 2) 57 | result += write_utf16(self.char, 2) 58 | result += write_int(self.glyph_id, 4) 59 | return result 60 | 61 | 62 | class Glyph: 63 | ENTRY_SIZE = 40 64 | 65 | @staticmethod 66 | def parse(reader): 67 | result = Glyph() 68 | result.texture = read_int(reader, 4) 69 | result.u1 = read_float(reader) 70 | result.v1 = read_float(reader) 71 | result.u2 = read_float(reader) 72 | result.v2 = read_float(reader) 73 | result.width = read_float(reader) 74 | result.height = read_float(reader) # same as font.height, sometimes diff by 1 75 | result.above = read_float(reader) 76 | result.below = read_float(reader) # same as font.below 77 | result.horiz = read_float(reader) # same as font.horiz and equal 0 78 | return result 79 | 80 | def serialize(self): 81 | result = bytearray() 82 | result += write_int(self.texture, 4) 83 | result += write_float(self.u1) 84 | result += write_float(self.v1) 85 | result += write_float(self.u2) 86 | result += write_float(self.v2) 87 | result += write_float(self.width) 88 | result += write_float(self.height) 89 | result += write_float(self.above) 90 | result += write_float(self.below) 91 | result += write_float(self.horiz) 92 | return result 93 | 94 | 95 | class Font: 96 | ENTRY_SIZE = 20 97 | 98 | @staticmethod 99 | def parse(reader): 100 | result = Font() 101 | result.id = read_int(reader, 4) 102 | result.width = read_float(reader) 103 | result.height = read_float(reader) 104 | result.below = read_float(reader) 105 | result.horiz = read_float(reader) 106 | return result 107 | 108 | def serialize(self): 109 | result = bytearray() 110 | result += write_int(self.id, 4) 111 | result += write_float(self.width) 112 | result += write_float(self.height) 113 | result += write_float(self.below) 114 | result += write_float(self.horiz) 115 | return result 116 | 117 | 118 | class Event: 119 | ENTRY_SIZE = 40 120 | 121 | @staticmethod 122 | def parse(reader): 123 | result = Event() 124 | result.id = read_int(reader, 4) 125 | result.idx = read_int(reader, 4) 126 | result.name = read_utf8(reader, 32) 127 | return result 128 | 129 | def serialize(self): 130 | result = bytearray() 131 | result += write_int(self.id, 4) 132 | result += write_int(self.idx, 4) 133 | result += write_utf8(self.name, 32) 134 | return result 135 | 136 | 137 | class Message: 138 | ENTRY_SIZE = 16 139 | 140 | @staticmethod 141 | def parse(reader): 142 | result = Message() 143 | result.texts = [] 144 | texts_offset = read_int(reader, 4) 145 | texts_count = read_int(reader, 4) 146 | result.seq_number = read_int(reader, 4) 147 | result.event_id = read_int(reader, 4) 148 | 149 | last_pos = reader.tell() 150 | reader.seek(texts_offset) 151 | for i in range(texts_count): 152 | result.texts.append(Text.parse(reader)) 153 | reader.seek(last_pos) 154 | 155 | return result 156 | 157 | def serialize(self, texts_offset): 158 | result = bytearray() 159 | result += write_int(texts_offset, 4) 160 | result += write_int(len(self.texts), 4) 161 | result += write_int(self.seq_number, 4) 162 | result += write_int(self.event_id, 4) 163 | return result 164 | 165 | def as_string(self, symbols): 166 | # using first text - other texts have the same content, but using different font 167 | return self.texts[0].as_string(symbols) 168 | 169 | def put_string(self, value, symbols, fonts): 170 | for text in self.texts: 171 | text.put_string(value, symbols, fonts) 172 | 173 | 174 | class Text: 175 | ENTRY_SIZE = 20 176 | 177 | @staticmethod 178 | def parse(reader): 179 | result = Text() 180 | result.lines = [] 181 | lines_offset = read_int(reader, 4) 182 | lines_count = read_int(reader, 4) 183 | result.vpos = read_int(reader, 4) 184 | result.hpos = read_int(reader, 4) 185 | result.font = read_int(reader, 4) # ???? it is font ? 186 | 187 | last_pos = reader.tell() 188 | reader.seek(lines_offset) 189 | for i in range(lines_count): 190 | result.lines.append(Line.parse(reader)) 191 | reader.seek(last_pos) 192 | 193 | return result 194 | 195 | def serialize(self, lines_offset): 196 | result = bytearray() 197 | result += write_int(lines_offset, 4) 198 | result += write_int(len(self.lines), 4) 199 | result += write_int(self.vpos, 4) 200 | result += write_int(self.hpos, 4) 201 | result += write_int(self.font, 4) 202 | return result 203 | 204 | def as_string(self, symbols): 205 | return "\n".join([line.as_string(symbols) for line in self.lines]) 206 | 207 | def put_string(self, value, symbols, fonts): 208 | font = fonts[self.font] 209 | self.lines = [ 210 | Line.from_string(line, font, symbols) for line in value.split("\n") 211 | ] 212 | 213 | 214 | class Line: 215 | ENTRY_SIZE = 24 216 | 217 | @staticmethod 218 | def from_string(value, font, symbols): 219 | result = Line() 220 | result.content = [] 221 | result.padding = 0 222 | result.below = font.line_below_value() 223 | result.horiz = 0 224 | result.put_string(value, symbols, font) 225 | return result 226 | 227 | @staticmethod 228 | def parse(reader): 229 | result = Line() 230 | result.content = [] 231 | content_offset = read_int(reader, 4) 232 | result.padding = read_int(reader, 4) 233 | content_length = read_int(reader, 4) 234 | read_int(reader, 4) # skip length2 235 | result.below = read_float(reader) 236 | result.horiz = read_float(reader) 237 | 238 | last_pos = reader.tell() 239 | reader.seek(content_offset) 240 | for i in range(content_length): 241 | val = read_int(reader, 2) 242 | if val < -32000: 243 | val = val & 0xFFFF 244 | result.content.append(val) 245 | reader.seek(last_pos) 246 | 247 | return result 248 | 249 | def serialize(self, content_offset): 250 | result = bytearray() 251 | result += write_int(content_offset, 4) 252 | result += write_int(self.padding, 4) 253 | result += write_int(len(self.content), 4) 254 | result += write_int(len(self.content), 4) 255 | result += write_float(self.below) 256 | result += write_float(self.horiz) 257 | return result 258 | 259 | def as_string(self, symbols): 260 | result = "" 261 | idx = 0 262 | while idx < len(self.content): 263 | char_id = self.content[idx] 264 | if char_id < 0x8000: 265 | result += symbols[char_id].char 266 | idx += 2 # skip kerning 267 | elif char_id == 0x8001: 268 | result += " " 269 | idx += 2 # skip font id 270 | elif char_id == 0x8000: 271 | # text end 272 | idx += 1 273 | elif char_id == 0x8020: 274 | result += "" 275 | idx += 2 276 | else: 277 | # using '<' and '>' for tagging - hopefully it doesn't break anything 278 | result += "", i) 291 | self.content.append(0x8020) 292 | self.content.append(int(value[i1:i2])) 293 | i = i2 294 | elif value[i] == " ": 295 | self.content.append(0x8001) 296 | self.content.append(font.id) 297 | else: 298 | char_id = -1 299 | for id, symbol in enumerate(symbols): 300 | if symbol.font_id == font.id and symbol.char == value[i]: 301 | char_id = id 302 | if char_id < 0: 303 | raise Exception( 304 | "No glyph for '" + value[i] + "' in font " + font.id 305 | ) 306 | self.content.append(char_id) 307 | if i > 0: 308 | self.content.append(font.get_kerning(value[i - 1], value[i])) 309 | else: 310 | self.content.append(0) 311 | i += 1 312 | self.content.append(0x8000) 313 | 314 | 315 | class File: 316 | @staticmethod 317 | def parse(reader): 318 | result = File() 319 | reader.seek(0) 320 | result.header = Header.parse(reader) 321 | 322 | reader.seek(result.header.messages_offset) 323 | result.messages = [] 324 | for i in range(result.header.messages_count): 325 | result.messages.append(Message.parse(reader)) 326 | 327 | reader.seek(result.header.symbols_offset) 328 | result.symbols = [] 329 | for i in range(result.header.symbols_count): 330 | result.symbols.append(Symbol.parse(reader)) 331 | 332 | reader.seek(result.header.glyphs_offset) 333 | result.glyphs = [] 334 | for i in range(result.header.glyphs_count): 335 | result.glyphs.append(Glyph.parse(reader)) 336 | 337 | reader.seek(result.header.fonts_offset) 338 | result.fonts = [] 339 | for i in range(result.header.fonts_count): 340 | result.fonts.append(Font.parse(reader)) 341 | 342 | reader.seek(result.header.events_offset) 343 | result.events = [] 344 | for i in range(result.header.events_count): 345 | result.events.append(Event.parse(reader)) 346 | return result 347 | 348 | def serialize(self): 349 | result = bytearray() 350 | 351 | current_offset = Header.ENTRY_SIZE 352 | 353 | strings = [] 354 | strings_offsets = [] 355 | 356 | texts = [] 357 | texts_offsets = [] 358 | 359 | lines = [] 360 | lines_offsets = [] 361 | 362 | for message in self.messages: 363 | for text in message.texts: 364 | texts.append(text) 365 | for line in text.lines: 366 | strings.append(line.content) 367 | strings_offsets.append(current_offset) 368 | current_offset += len(line.content) * 2 369 | lines.append(line) 370 | current_offset += calc_eager_padding(current_offset, 4) 371 | 372 | header = Header() 373 | header.messages_offset = current_offset 374 | header.messages_count = len(self.messages) 375 | current_offset += header.messages_count * Message.ENTRY_SIZE 376 | current_offset += calc_eager_padding(current_offset, 4) 377 | 378 | for i in range(len(texts)): 379 | texts_offsets.append(current_offset + i * Text.ENTRY_SIZE) 380 | current_offset += len(texts) * Text.ENTRY_SIZE 381 | current_offset += calc_eager_padding(current_offset, 4) 382 | 383 | for i in range(len(lines)): 384 | lines_offsets.append(current_offset + i * Line.ENTRY_SIZE) 385 | current_offset += len(lines) * Line.ENTRY_SIZE 386 | current_offset += calc_eager_padding(current_offset, 4) 387 | 388 | header.symbols_offset = current_offset 389 | header.symbols_count = len(self.symbols) 390 | current_offset += header.symbols_count * Symbol.ENTRY_SIZE + 4 391 | 392 | header.glyphs_offset = current_offset 393 | header.glyphs_count = len(self.glyphs) 394 | current_offset += header.glyphs_count * Glyph.ENTRY_SIZE + 4 395 | 396 | header.fonts_offset = current_offset 397 | header.fonts_count = len(self.fonts) 398 | current_offset += header.fonts_count * Font.ENTRY_SIZE + 4 399 | 400 | header.events_offset = current_offset 401 | header.events_count = len(self.events) 402 | 403 | result += header.serialize() 404 | for string in strings: 405 | for v in string: 406 | result += write_int(v, 2) 407 | result += write_eager_padding(len(result), 4) 408 | 409 | texts_offset_idx = 0 410 | for message in self.messages: 411 | texts_offset = texts_offsets[texts_offset_idx] 412 | texts_offset_idx += len(message.texts) 413 | result += message.serialize(texts_offset) 414 | result += write_eager_padding(len(result), 4) 415 | 416 | lines_offset_idx = 0 417 | for text in texts: 418 | lines_offset = lines_offsets[lines_offset_idx] 419 | lines_offset_idx += len(text.lines) 420 | result += text.serialize(lines_offset) 421 | result += write_eager_padding(len(result), 4) 422 | 423 | strings_idx = 0 424 | for line in lines: 425 | strings_offset = strings_offsets[strings_idx] 426 | strings_idx += 1 427 | result += line.serialize(strings_offset) 428 | result += write_eager_padding(len(result), 4) 429 | 430 | for symbol in self.symbols: 431 | result += symbol.serialize() 432 | result += write_eager_padding(len(result), 4) 433 | 434 | for glyph in self.glyphs: 435 | result += glyph.serialize() 436 | result += write_eager_padding(len(result), 4) 437 | 438 | for font in self.fonts: 439 | result += font.serialize() 440 | result += write_eager_padding(len(result), 4) 441 | 442 | for event in self.events: 443 | result += event.serialize() 444 | 445 | return result 446 | 447 | def get_strings(self, lang): 448 | result = dict() 449 | for msg in self.messages: 450 | matching_events = list(filter(lambda e: e.id == msg.event_id, self.events)) 451 | assert len(matching_events) == 1 452 | event = matching_events[0].name 453 | result[event] = msg.as_string(self.symbols) 454 | return result 455 | 456 | def get_fonts_for_messages(self): 457 | result = dict() 458 | for msg in self.messages: 459 | matching_events = list(filter(lambda e: e.id == msg.event_id, self.events)) 460 | assert len(matching_events) == 1 461 | event = matching_events[0].name 462 | result[event] = set() 463 | for text in msg.texts: 464 | result[event].add(text.font) 465 | return result 466 | 467 | def get_glyphs(self, textures, font_id): 468 | result = {} 469 | for symbol in self.symbols: 470 | if symbol.font_id != font_id: 471 | continue 472 | glyph = self.glyphs[symbol.glyph_id] 473 | texture = textures[0] 474 | u1 = glyph.u1 * texture.width 475 | u2 = glyph.u2 * texture.width 476 | v1 = glyph.v1 * texture.height 477 | v2 = glyph.v2 * texture.height 478 | result[symbol.char] = texture.crop((u1, v1, u2, v2)) 479 | return result 480 | 481 | def remove_all_glyphs(self): 482 | self.symbols = [] 483 | self.glyphs = [] 484 | pass 485 | 486 | def put_glyph( 487 | self, char, font_id, x, y, width, height, texture_width, texture_height 488 | ): 489 | glyph = Glyph() 490 | glyph.texture = 0 491 | glyph.u1 = x / texture_width 492 | glyph.v1 = y / texture_height 493 | glyph.u2 = (x + width) / texture_width 494 | glyph.v2 = (y + height) / texture_height 495 | glyph.width = width 496 | glyph.height = height 497 | glyph.above = 0 498 | font = next(f for f in self.fonts if f.id == font_id) 499 | glyph.below = font.below 500 | glyph.horiz = font.horiz 501 | self.glyphs.append(glyph) 502 | 503 | symbol = Symbol() 504 | symbol.font_id = font_id 505 | symbol.char = char 506 | symbol.glyph_id = len(self.glyphs) - 1 507 | self.symbols.append(symbol) 508 | pass 509 | 510 | def put_strings(self, mapping, fonts): 511 | for msg in self.messages: 512 | matching_events = list(filter(lambda e: e.id == msg.event_id, self.events)) 513 | assert len(matching_events) == 1 514 | event = matching_events[0].name 515 | value = mapping[event] 516 | msg.put_string(value, self.symbols, fonts) 517 | -------------------------------------------------------------------------------- /tools/format/pak.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | from format.utils import * 4 | import format.charnames as charnames 5 | import zlib 6 | from io import BytesIO 7 | 8 | 9 | class Segment: 10 | def parse(reader, entry): 11 | result = Segment() 12 | result.entry = entry 13 | result.content = read_bytes(reader, entry.real_size) 14 | return result 15 | 16 | def unzip(self): 17 | return zlib.decompress(self.content[4:]) 18 | 19 | def zip_and_put_data(self, data): 20 | zipped_bytes = zlib.compress(data, 1) 21 | self.entry.compressed_size = len(data) 22 | self.content = bytearray() 23 | self.content += write_int(len(zipped_bytes), 4) 24 | self.content += zipped_bytes 25 | self.content += write_padding(len(self.content), 4) 26 | 27 | def serialize(self): 28 | return self.content 29 | 30 | 31 | class SegmentEntry: 32 | def parse(reader): 33 | result = SegmentEntry() 34 | result.type = read_int(reader, 4) 35 | if result.type == 0: 36 | return None 37 | result.compressed_size = read_int(reader, 4) 38 | result.offset = read_int(reader, 4) 39 | result.real_size = -1 40 | return result 41 | 42 | def serialize(self): 43 | result = bytearray() 44 | result += write_int(self.type, 4) 45 | result += write_int(self.compressed_size, 4) 46 | result += write_int(self.offset, 4) 47 | return result 48 | 49 | 50 | class File: 51 | @staticmethod 52 | def parse(reader): 53 | result = File() 54 | reader.seek(0) 55 | entries = [] 56 | entry = SegmentEntry.parse(reader) 57 | while entry != None: 58 | entries.append(entry) 59 | entry = SegmentEntry.parse(reader) 60 | pass 61 | 62 | offsets = [e.offset for e in entries] 63 | real_sizes = [o2 - o1 for o1, o2 in zip(offsets[0:], offsets[1:])] 64 | for entry, real_size in zip(entries, real_sizes): 65 | entry.real_size = real_size 66 | 67 | result.segments = [] 68 | for entry in entries: 69 | reader.seek(entry.offset) 70 | result.segments.append(Segment.parse(reader, entry)) 71 | return result 72 | 73 | def serialize(self): 74 | result = bytearray() 75 | offset = 12 * len(self.segments) + 4 76 | for segment in self.segments: 77 | segment.entry.offset = offset 78 | offset += len(segment.content) 79 | 80 | for segment in self.segments: 81 | result += segment.entry.serialize() 82 | result += write_int(0, 4) 83 | 84 | for segment in self.segments: 85 | result += segment.serialize() 86 | return result 87 | 88 | def strings_segment_id(self): 89 | for id in range(len(self.segments)): 90 | if self.segments[id].entry.compressed_size == 115220: 91 | return id; 92 | return 25 # fallback 93 | 94 | def get_strings(self, lang): 95 | id = self.strings_segment_id() 96 | return charnames.File.parse(BytesIO(self.segments[id].unzip())).get_strings( 97 | lang 98 | ) 99 | 100 | def put_strings(self, mapping, lang): 101 | id = self.strings_segment_id() 102 | parsedcharnames = charnames.File.parse(BytesIO(self.segments[id].unzip())) 103 | parsedcharnames.put_strings(lang, mapping) 104 | self.segments[id].zip_and_put_data(parsedcharnames.serialize()) 105 | -------------------------------------------------------------------------------- /tools/format/properties.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | from io import TextIOWrapper 4 | 5 | # java .properties file subset: 6 | # no comments 7 | # key has only ASCII characters 8 | # : and = are not allowed in key, even escaped 9 | # = is always key-value separator 10 | # no multiline (no escaping endline terminator) 11 | # all non-ASCII characters are escaped (keep_non_ascii=True will use UTF-8 rather than ASCII encoding) 12 | # there are no characters outside Unicode BMP (no surogate pairs/32-bit characters) 13 | 14 | 15 | def parse_properties(reader): 16 | result = dict() 17 | reader.seek(0) 18 | text_reader = TextIOWrapper(reader) 19 | for line in text_reader.readlines(): 20 | key, sep, value = ( 21 | line.rstrip("\r\n").encode("latin1", "backslashreplace").decode("unicode_escape").partition("=") 22 | ) 23 | result[key] = value 24 | 25 | return result 26 | 27 | 28 | # escape manually, as python will use \xhh rather than \u00hh 29 | def escape_nonascii(text, keep_non_ascii=False): 30 | result = "" 31 | for c in text: 32 | if ord(c) >= 0x10000: 33 | raise Exception("Unsupported character: U+{:x}".format(ord(c))) 34 | if ord(c) >= 0x7F and not keep_non_ascii: 35 | result += "\\u{:04x}".format(ord(c)) 36 | elif c == "\t": 37 | result += "\\t" 38 | elif c == "\n": 39 | result += "\\n" 40 | elif c == "\r": 41 | result += "\\r" 42 | elif c == "\\": 43 | result += "\\\\" 44 | elif ord(c) <= 0x1F: 45 | result += "\\u{:04x}".format(ord(c)) 46 | else: 47 | result += c 48 | if result[-1] == "\\": 49 | result += "" # Workaround for Omega-T 50 | return result 51 | 52 | 53 | def serialize_properties(kv, keep_non_ascii=False): 54 | result = bytearray() 55 | for key, value in kv.items(): 56 | result += (escape_nonascii(key + "=" + value, keep_non_ascii) + "\n").encode( 57 | "utf-8" 58 | ) 59 | return result 60 | -------------------------------------------------------------------------------- /tools/format/smd.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | from format.utils import * 4 | 5 | 6 | class Entry: 7 | @staticmethod 8 | def parse(reader): 9 | result = Entry() 10 | result.id = read_utf16(reader, 0x80) 11 | result.number = read_int(reader, 8) 12 | result.text = read_utf16(reader, 0x800) 13 | return result 14 | 15 | def serialize(self): 16 | result = bytearray() 17 | result += write_utf16(self.id, 0x80) 18 | result += write_int(self.number, 8) 19 | result += write_utf16(self.text, 0x800) 20 | return result 21 | 22 | 23 | class File: 24 | @staticmethod 25 | def parse(reader): 26 | result = File() 27 | reader.seek(0) 28 | count = read_int(reader, 4) 29 | 30 | result.entries = [] 31 | for i in range(count): 32 | result.entries.append(Entry.parse(reader)) 33 | 34 | return result 35 | 36 | def serialize(self): 37 | result = bytearray() 38 | result += write_int(len(self.entries), 4) 39 | for e in self.entries: 40 | result += e.serialize() 41 | return result 42 | 43 | def get_strings(self, lang): 44 | result = dict() 45 | for e in self.entries: 46 | result[e.id] = e.text 47 | return result 48 | 49 | def put_strings(self, mapping, lang): 50 | for e in self.entries: 51 | e.text = mapping[e.id] 52 | -------------------------------------------------------------------------------- /tools/format/tmd.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | from format.utils import * 4 | 5 | 6 | class Entry: 7 | @staticmethod 8 | def parse(reader): 9 | result = Entry() 10 | idsize = read_int(reader, 4) * 2 11 | result.id = read_utf16(reader, idsize) 12 | textsize = read_int(reader, 4) * 2 13 | result.text = read_utf16(reader, textsize) 14 | return result 15 | 16 | def serialize(self): 17 | result = bytearray() 18 | idsize = len(self.id) + 1 19 | result += write_int(idsize, 4) 20 | result += write_utf16(self.id, idsize * 2) 21 | textsize = len(self.text) + 1 22 | result += write_int(textsize, 4) 23 | result += write_utf16(self.text, textsize * 2) 24 | return result 25 | 26 | 27 | class File: 28 | @staticmethod 29 | def parse(reader): 30 | result = File() 31 | reader.seek(0) 32 | count = read_int(reader, 4) 33 | 34 | result.entries = [] 35 | for i in range(count): 36 | result.entries.append(Entry.parse(reader)) 37 | 38 | return result 39 | 40 | def serialize(self): 41 | result = bytearray() 42 | result += write_int(len(self.entries), 4) 43 | for e in self.entries: 44 | result += e.serialize() 45 | return result 46 | 47 | def get_strings(self, lang): 48 | result = dict() 49 | for e in self.entries: 50 | result[e.id] = e.text 51 | return result 52 | 53 | def put_strings(self, mapping, lang): 54 | for e in self.entries: 55 | e.text = mapping[e.id] 56 | -------------------------------------------------------------------------------- /tools/format/utils.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import struct 4 | 5 | 6 | def assert_magic(magic, reference): 7 | l = len(reference) 8 | if magic[0:l] != reference: 9 | raise Exception( 10 | "Invalid magic value in file: expected " 11 | + reference.hex() 12 | + ", was: " 13 | + magic[0:l].hex() 14 | ) 15 | 16 | 17 | def read_bytes(reader, byte_count): 18 | return reader.read(byte_count) 19 | 20 | 21 | def peek_bytes(reader, byte_count): 22 | pos = reader.tell() 23 | bytes = reader.read(byte_count) 24 | reader.seek(pos) 25 | return bytes 26 | 27 | 28 | def read_int(reader, byte_count): 29 | return int.from_bytes(reader.read(byte_count), "little", signed=True) 30 | 31 | 32 | def read_uint(reader, byte_count): 33 | return int.from_bytes(reader.read(byte_count), "little", signed=False) 34 | 35 | 36 | def write_int(value, byte_count): 37 | if value < 0: 38 | return value.to_bytes(byte_count, "little", signed=True) 39 | else: 40 | return value.to_bytes(byte_count, "little", signed=False) 41 | 42 | 43 | def read_be_int(reader, byte_count): # big endian 44 | return int.from_bytes(reader.read(byte_count), "big", signed=True) 45 | 46 | 47 | def write_be_int(value, byte_count): # big endian 48 | if value < 0: 49 | return value.to_bytes(byte_count, "big", signed=True) 50 | else: 51 | return value.to_bytes(byte_count, "big", signed=False) 52 | 53 | 54 | def read_float(reader): 55 | return struct.unpack("f", reader.read(4))[0] 56 | 57 | 58 | def write_float(value): 59 | return struct.pack("f", value) 60 | 61 | 62 | def read_utf8(reader, byte_count): 63 | return reader.read(byte_count).decode("utf-8").rstrip("\0") 64 | 65 | 66 | def read_zero_terminated_utf8(reader): 67 | init_offset = reader.tell() 68 | while reader.read(1) not in {b"\0", b""}: 69 | pass 70 | byte_count = reader.tell() - init_offset 71 | reader.seek(init_offset) 72 | return read_utf8(reader, byte_count) 73 | 74 | 75 | def write_utf8(value, byte_count): 76 | return value.encode("utf-8").ljust(byte_count, b"\0") 77 | 78 | 79 | def read_utf16(reader, byte_count): 80 | return reader.read(byte_count).decode("utf-16-le").rstrip("\0") 81 | 82 | 83 | def write_utf16(value, byte_count): 84 | return value.encode("utf-16-le").ljust(byte_count, b"\0") 85 | 86 | 87 | def read_padding(reader, mod): 88 | offset = reader.tell() 89 | padding_size = mod - (offset % mod) 90 | if padding_size != mod: 91 | return reader.read(padding_size) 92 | else: 93 | return b"" 94 | 95 | 96 | def write_padding(offset, mod): 97 | padding_size = mod - (offset % mod) 98 | if padding_size != mod: 99 | return b"\0" * padding_size 100 | else: 101 | return b"" 102 | 103 | 104 | def calc_eager_padding(offset, mod): 105 | return mod - (offset % mod) 106 | 107 | 108 | def write_eager_padding(offset, mod): 109 | return b"\0" * calc_eager_padding(offset, mod) 110 | -------------------------------------------------------------------------------- /tools/format/wta.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | from format.utils import * 4 | import os 5 | 6 | 7 | class Header: 8 | HEADER_SIZE = 32 9 | 10 | @staticmethod 11 | def parse(reader): 12 | result = Header() 13 | result.magic = read_bytes(reader, 8) 14 | assert_magic(result.magic, b"WTB\0") 15 | result.textures_count = read_int(reader, 4) 16 | result.offsets_offset = read_int(reader, 4) 17 | result.size_offset = read_int(reader, 4) 18 | result.flags_offset = read_int(reader, 4) 19 | result.idx_offset = read_int(reader, 4) 20 | result.info_offset = read_int(reader, 4) 21 | return result 22 | 23 | def serialize(self): 24 | result = bytearray() 25 | result += self.magic 26 | result += write_int(self.textures_count, 4) 27 | result += write_int(self.offsets_offset, 4) 28 | result += write_int(self.size_offset, 4) 29 | result += write_int(self.flags_offset, 4) 30 | result += write_int(self.idx_offset, 4) 31 | result += write_int(self.info_offset, 4) 32 | return result 33 | 34 | 35 | class Entry: 36 | def __init__(self): 37 | self.idx = None 38 | self.offset = None 39 | self.size = None 40 | self.flags = None 41 | self.info = None 42 | 43 | def is_astc(self): 44 | if not self.info: 45 | return False 46 | return self.info[4] in {0x79, 0x7D, 0x8B} 47 | 48 | def tex_width(self): 49 | return int.from_bytes(self.info[12:15], "little", signed=False) 50 | 51 | def tex_height(self): 52 | return int.from_bytes(self.info[16:19], "little", signed=False) 53 | 54 | def update_astc_info(self): 55 | if not self.is_astc(): 56 | return 57 | self.info = bytearray(self.info) 58 | self.info[4] = 0x79 # ASTC_4x4_UNORM 59 | self.info[32:36] = self.size.to_bytes(4, "little") 60 | 61 | def astc_header(self): 62 | return ( 63 | b"\x13\xAB\xA1\x5C\x06\x06\0" 64 | + self.info[12:15] 65 | + self.info[16:19] 66 | + b"\1\0\0" 67 | ) 68 | 69 | 70 | class File: 71 | @staticmethod 72 | def parse(reader): 73 | result = File() 74 | reader.seek(0) 75 | result.header = Header.parse(reader) 76 | 77 | result.textures = [Entry() for i in range(result.header.textures_count)] 78 | 79 | reader.seek(result.header.offsets_offset) 80 | for i in range(result.header.textures_count): 81 | result.textures[i].offset = read_int(reader, 4) 82 | 83 | reader.seek(result.header.size_offset) 84 | for i in range(result.header.textures_count): 85 | result.textures[i].size = read_int(reader, 4) 86 | 87 | reader.seek(result.header.flags_offset) 88 | for i in range(result.header.textures_count): 89 | result.textures[i].flags = read_bytes(reader, 4) 90 | 91 | reader.seek(result.header.idx_offset) 92 | for i in range(result.header.textures_count): 93 | result.textures[i].idx = read_bytes(reader, 4) 94 | 95 | result.has_info_table = result.header.info_offset > 0 96 | if result.has_info_table: 97 | reader.seek(0, os.SEEK_END) 98 | end_pos = reader.tell() 99 | info_record_size = int( 100 | (end_pos - result.header.info_offset) / result.header.textures_count 101 | ) 102 | if info_record_size < 256 and info_record_size > 0: 103 | info_record_size = 20 104 | reader.seek(result.header.info_offset) 105 | for i in range(result.header.textures_count): 106 | result.textures[i].info = read_bytes(reader, info_record_size) 107 | 108 | return result 109 | 110 | def serialize(self): 111 | result = bytearray(b"\0" * Header.HEADER_SIZE) # placeholder 112 | self.header.textures_count = len(self.textures) 113 | 114 | self.header.offsets_offset = len(result) 115 | texture_offset = 0 116 | TEXTURE_OFFSET_PADDING = 0x1000 117 | for texture in self.textures: 118 | result += write_int(texture_offset, 4) 119 | texture_offset += texture.size 120 | texture_offset += ( 121 | TEXTURE_OFFSET_PADDING - texture_offset % TEXTURE_OFFSET_PADDING 122 | ) % TEXTURE_OFFSET_PADDING 123 | result += write_padding(len(result), 32) 124 | 125 | self.header.size_offset = len(result) 126 | for texture in self.textures: 127 | result += write_int(texture.size, 4) 128 | result += write_padding(len(result), 32) 129 | 130 | self.header.flags_offset = len(result) 131 | for texture in self.textures: 132 | result += texture.flags 133 | result += write_padding(len(result), 32) 134 | 135 | self.header.idx_offset = len(result) 136 | for texture in self.textures: 137 | result += texture.idx 138 | if self.has_info_table: 139 | result += write_padding(len(result), 32) 140 | else: 141 | result += write_padding(len(result), 16) 142 | 143 | if self.has_info_table: 144 | self.header.info_offset = len(result) 145 | for texture in self.textures: 146 | result += texture.info 147 | result += write_padding(len(result), 16) 148 | else: 149 | self.header.info_offset = 0 150 | 151 | result[0 : Header.HEADER_SIZE] = self.header.serialize() 152 | 153 | return result 154 | -------------------------------------------------------------------------------- /tools/get_strings.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import argparse 4 | import os 5 | 6 | import format.smd as smd 7 | import format.tmd as tmd 8 | import format.bin as bin 9 | import format.mcd as mcd 10 | import format.pak as pak 11 | import format.properties as properties 12 | 13 | 14 | def extract_strings_to_file( 15 | input_filename, output_filename, lang="en", keep_non_ascii=False 16 | ): 17 | if lang not in {"jp", "en", "fr", "it", "de", "es", "ko", "zh"}: 18 | raise Exception("Language " + lang + " is not supported") 19 | 20 | file_ext = os.path.splitext(input_filename)[1] 21 | 22 | parsed = None 23 | with open(input_filename, "rb") as in_file: 24 | if file_ext == ".bin": 25 | parsed = bin.File.parse(in_file) 26 | elif file_ext == ".smd": 27 | parsed = smd.File.parse(in_file) 28 | elif file_ext == ".tmd": 29 | parsed = tmd.File.parse(in_file) 30 | elif file_ext == ".mcd": 31 | parsed = mcd.File.parse(in_file) 32 | elif file_ext == ".pak": 33 | parsed = pak.File.parse(in_file) 34 | else: 35 | raise Exception( 36 | "Unable to extract " + input_filename + ": unknown file extenstion" 37 | ) 38 | 39 | with open(output_filename, "wb") as out_file: 40 | out_file.write( 41 | properties.serialize_properties(parsed.get_strings(lang), keep_non_ascii) 42 | ) 43 | 44 | 45 | if __name__ == "__main__": 46 | parser = argparse.ArgumentParser() 47 | parser.add_argument("input", help="source file name") 48 | parser.add_argument("output", help="target file name (*.properties)") 49 | parser.add_argument( 50 | "--lang", 51 | help="source laguage (default: en, affects only .bin and .pak files)", 52 | default="en", 53 | ) 54 | parser.add_argument( 55 | "--keep-non-ascii", 56 | help="keep non-ascii charater as UTF-8 instead of escaping them (will produce non-standard .properties file)", 57 | action="store_true", 58 | ) 59 | 60 | args = parser.parse_args() 61 | extract_strings_to_file(args.input, args.output, args.lang, args.keep_non_ascii) 62 | -------------------------------------------------------------------------------- /tools/put_glyphs.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import argparse 4 | import format.ftb as ftb 5 | from PIL import Image 6 | 7 | 8 | def add_glyphs(font, texture, page, chars): 9 | for char, glyph in chars: 10 | x, y = font.find_space_for_glyph(glyph.size, texture.size, page) 11 | font.add_character(char, page, glyph.width, glyph.height, x, y) 12 | texture.paste(glyph, (x, y)) 13 | 14 | 15 | if __name__ == "__main__": 16 | parser = argparse.ArgumentParser() 17 | parser.add_argument("input_ftb", help="source font file") 18 | parser.add_argument("input_texture", help="source texture file (can be .dds)") 19 | parser.add_argument("output_ftb", help="target font file") 20 | parser.add_argument( 21 | "output_texture", 22 | help="target texture file (cannot be .dds, but .png can be used)", 23 | ) 24 | parser.add_argument( 25 | "--page", help="texture number", required=True, type=int, 26 | ) 27 | parser.add_argument( 28 | "--char", 29 | help="character id and glyph image", 30 | metavar=("CHARID", "CHARIMG"), 31 | nargs=2, 32 | action="append", 33 | ) 34 | 35 | args = parser.parse_args() 36 | 37 | font = None 38 | with open(args.input_ftb, "rb") as input_ftb: 39 | font = ftb.File.parse(input_ftb) 40 | texture = Image.open(args.input_texture) 41 | 42 | chars = [(chr(int(c)), Image.open(tex)) for c, tex in args.char] 43 | 44 | add_glyphs(font, texture, args.page, chars) 45 | 46 | with open(args.output_ftb, "wb") as out_ftb: 47 | out_ftb.write(font.serialize()) 48 | texture.save(args.output_texture) 49 | -------------------------------------------------------------------------------- /tools/put_strings.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import argparse 4 | import os 5 | 6 | import format.smd as smd 7 | import format.tmd as tmd 8 | import format.bin as bin 9 | import format.mcd as mcd 10 | import format.pak as pak 11 | import format.properties as properties 12 | 13 | 14 | def insert_strings_to_file( 15 | input_filename, properties_filename, output_filename, lang="en" 16 | ): 17 | if lang not in {"jp", "en", "fr", "it", "de", "es"}: 18 | raise Exception("Language " + lang + " is not supported") 19 | 20 | file_ext = os.path.splitext(input_filename)[1] 21 | 22 | parsed = None 23 | with open(input_filename, "rb") as in_file: 24 | if file_ext == ".bin": 25 | parsed = bin.File.parse(in_file) 26 | elif file_ext == ".smd": 27 | parsed = smd.File.parse(in_file) 28 | elif file_ext == ".tmd": 29 | parsed = tmd.File.parse(in_file) 30 | elif file_ext == ".pak": 31 | parsed = pak.File.parse(in_file) 32 | else: 33 | raise Exception( 34 | "Unable to extract " + input_filename + ": unknown file extenstion" 35 | ) 36 | 37 | mapping = None 38 | with open(properties_filename, "rb") as properties_file: 39 | mapping = properties.parse_properties(properties_file) 40 | 41 | parsed.put_strings(mapping, lang) 42 | 43 | with open(output_filename, "wb") as out_file: 44 | out_file.write(parsed.serialize()) 45 | 46 | 47 | if __name__ == "__main__": 48 | parser = argparse.ArgumentParser() 49 | parser.add_argument("input", help="source file name") 50 | parser.add_argument("strings", help="strings file name (*.properties)") 51 | parser.add_argument("output", help="target file name") 52 | parser.add_argument( 53 | "--lang", 54 | help="source laguage (default: en, affects only .bin and .pak files)", 55 | default="en", 56 | ) 57 | 58 | args = parser.parse_args() 59 | insert_strings_to_file(args.input, args.strings, args.output, args.lang) 60 | -------------------------------------------------------------------------------- /tools/put_strings_mcd.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import argparse 4 | import os 5 | import json 6 | import re 7 | from PIL import Image 8 | 9 | import format.mcd as mcd 10 | import format.ktb as ktb 11 | import format.properties as properties 12 | 13 | 14 | class Font: 15 | def __init__(self, id, font_json): 16 | self.id = id 17 | self.glyphs_dir = font_json["glyphs"] 18 | self.kerning_table = None 19 | if font_json["kerning"]: 20 | with open(font_json["kerning"], "rb") as input_ktb: 21 | self.kerning_table = ktb.File.parse(input_ktb) 22 | self.below_value = font_json["below"] 23 | 24 | def get_glyph_filename(self, char): 25 | return os.path.join(self.glyphs_dir, "{0:04x}.png".format(ord(char))) 26 | 27 | def get_kerning(self, left, right): 28 | if not self.kerning_table: 29 | return 0 30 | else: 31 | return self.kerning_table.get_kerning(left, right) 32 | 33 | def line_below_value(self): 34 | return self.below_value 35 | 36 | 37 | def build_fonts(json_filename): 38 | raw_fonts = None 39 | with open(json_filename, "rb") as json_file: 40 | raw_fonts = json.load(json_file) 41 | result = {} 42 | for id, font_json in raw_fonts.items(): 43 | result[int(id)] = Font(int(id), font_json) 44 | return result 45 | 46 | 47 | def get_glyphs(parsed_mcd, mapping, fonts): 48 | chars_per_font = {id: set() for id in fonts.keys()} 49 | for event, fonts_ids in parsed_mcd.get_fonts_for_messages().items(): 50 | chars = set() 51 | # strip spaces and special chars 52 | for char in re.sub("\n| |", "", mapping[event]): 53 | chars.add(char) 54 | for font_id in fonts_ids: 55 | chars_per_font[font_id] |= chars 56 | result = [] 57 | for font_id, chars in chars_per_font.items(): 58 | for char in chars: 59 | result.append((char, font_id, fonts[font_id].get_glyph_filename(char))) 60 | return result 61 | 62 | 63 | def generate_texture(glyphs, parsed_mcd): 64 | glyph_filenames = {cfi[2] for cfi in glyphs} 65 | glyph_images = [(Image.open(n), n) for n in glyph_filenames] 66 | glyph_images.sort(key=lambda elem: elem[1]) # to make deterministic 67 | glyph_images.sort(key=lambda elem: elem[0].width, reverse=True) 68 | glyph_images.sort(key=lambda elem: elem[0].height, reverse=True) 69 | 70 | def page_generator(): 71 | # (x,y,w,h) 72 | size = 256 73 | yield (0, 0, size, size) 74 | while True: 75 | yield (0, size, size, size * 2) 76 | yield (size, 0, size * 2, size * 2) 77 | size *= 2 78 | 79 | pages = page_generator() 80 | x_zero = y_zero = width = height = 0 81 | x = 1 82 | y = 1 83 | next_row = 0 84 | img_positions = {} 85 | for img, name in glyph_images: 86 | if x + img.width > width: 87 | x = x_zero 88 | y = next_row 89 | if y + img.height > height: 90 | x_zero, y_zero, width, height = next(pages) 91 | x = x_zero 92 | y = y_zero 93 | next_row = y + 1 94 | img_positions[name] = (x, y) 95 | x += img.width 96 | next_row = max(next_row, y + img.height) 97 | 98 | texture = Image.new("RGBA", (width, height), (0, 0, 0, 0)) 99 | for image, name in glyph_images: 100 | texture.paste(image, img_positions[name]) 101 | 102 | glyph_images_map = {name: image for image, name in glyph_images} 103 | for char, font_id, name in glyphs: 104 | x, y = img_positions[name] 105 | char_width, char_height = glyph_images_map[name].size 106 | parsed_mcd.put_glyph( 107 | char, font_id, x, y, char_width, char_height, width, height 108 | ) 109 | 110 | return texture 111 | 112 | 113 | def insert_strings_to_file(mcd, properties): 114 | 115 | parsed_mcd.put_strings(mapping, lang, fonts) 116 | 117 | 118 | if __name__ == "__main__": 119 | parser = argparse.ArgumentParser() 120 | parser.add_argument("input", help="source .mcd file name") 121 | parser.add_argument("strings", help="strings file name (*.properties)") 122 | parser.add_argument("fonts", help="fonts.json config file") 123 | parser.add_argument("output", help="target .mcd file name") 124 | parser.add_argument("texture", help="target .png texture file") 125 | 126 | args = parser.parse_args() 127 | 128 | parsed_mcd = None 129 | with open(args.input, "rb") as in_file: 130 | parsed_mcd = mcd.File.parse(in_file) 131 | 132 | mapping = None 133 | with open(args.strings, "rb") as properties_file: 134 | mapping = properties.parse_properties(properties_file) 135 | 136 | fonts = build_fonts(args.fonts) 137 | 138 | glyphs = get_glyphs(parsed_mcd, mapping, fonts) 139 | parsed_mcd.remove_all_glyphs() 140 | texture = generate_texture(glyphs, parsed_mcd) 141 | 142 | parsed_mcd.put_strings(mapping, fonts) 143 | 144 | with open(args.output, "wb") as out_file: 145 | out_file.write(parsed_mcd.serialize()) 146 | texture.save(args.texture) 147 | -------------------------------------------------------------------------------- /tools/repack_dat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import argparse 4 | import os 5 | import format.dat as dat 6 | 7 | parser = argparse.ArgumentParser() 8 | parser.add_argument("input_file", help=".dat or .dtt file name") 9 | parser.add_argument("output_file", help="output .dat or .dtt file name") 10 | parser.add_argument("replacement_files", help="files to replace in ", nargs="+") 11 | 12 | 13 | args = parser.parse_args() 14 | 15 | file = open(args.input_file, "rb") 16 | dat = dat.File.parse(file) 17 | 18 | for f in dat.files: 19 | for replacement_file in args.replacement_files: 20 | if os.path.basename(replacement_file) == f.name: 21 | f.bytes = open(replacement_file, "rb").read() 22 | 23 | out_file = open(args.output_file, "wb") 24 | out_file.write(dat.serialize()) 25 | -------------------------------------------------------------------------------- /tools/repack_wtp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import argparse 4 | import format.wta as wta 5 | from format.utils import * 6 | import swizzle 7 | 8 | 9 | def repack_wtp(parsed_wta, in_wtp, out_wtp, textures): 10 | for id, f in enumerate(parsed_wta.textures): 11 | if id in textures: 12 | texture = None 13 | with open(textures[id], "rb") as texture_file: 14 | texture = texture_file.read() 15 | if f.is_astc(): 16 | size_range = 4 if f.tex_height() >= 512 else 3 17 | texture = swizzle.swizzle( 18 | f.tex_width(), f.tex_height(), 4, 4, 16, 0, size_range, texture[16:] 19 | ) 20 | f.offset = out_wtp.tell() 21 | f.size = len(texture) 22 | if f.is_astc(): 23 | f.update_astc_info() 24 | out_wtp.write(texture) 25 | out_wtp.write(write_padding(out_wtp.tell(), 0x1000)) 26 | else: 27 | in_wtp.seek(f.offset) 28 | texture = in_wtp.read(f.size) 29 | f.offset = out_wtp.tell() 30 | f.size = len(texture) 31 | out_wtp.write(texture) 32 | out_wtp.write(write_padding(out_wtp.tell(), 0x1000)) 33 | 34 | 35 | if __name__ == "__main__": 36 | parser = argparse.ArgumentParser() 37 | parser.add_argument("input_wta", help="source wta file") 38 | parser.add_argument("input_wtp", help="source wtp file") 39 | parser.add_argument("output_wta", help="source wta file") 40 | parser.add_argument("output_wtp", help="source wtp file") 41 | parser.add_argument( 42 | "--texture", 43 | help="texture id and texture image (must be .dds)", 44 | metavar=("ID", "TEXTURE"), 45 | nargs=2, 46 | action="append", 47 | ) 48 | 49 | args = parser.parse_args() 50 | 51 | textures = {int(id): filename for id, filename in args.texture} 52 | 53 | wta_file = open(args.input_wta, "rb") 54 | in_wtp = open(args.input_wtp, "rb") 55 | parsed_wta = wta.File.parse(wta_file) 56 | 57 | out_wtp = open(args.output_wtp, "wb") 58 | repack_wtp(parsed_wta, in_wtp, out_wtp, textures) 59 | open(args.output_wta, "wb").write(parsed_wta.serialize()) 60 | -------------------------------------------------------------------------------- /tools/swizzle.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | #based on https://github.com/aboood40091/BNTX-Extractor/blob/master/swizzle.py 4 | 5 | def DIV_ROUND_UP(n, d): 6 | return (n + d - 1) // d 7 | 8 | def round_up(x, y): 9 | return ((x - 1) | (y - 1)) + 1 10 | 11 | 12 | def _swizzle(width, height, blkWidth, blkHeight, bpp, tileMode, size_range, data, toSwizzle): 13 | block_height = 1 << size_range 14 | 15 | width = DIV_ROUND_UP(width, blkWidth) 16 | height = DIV_ROUND_UP(height, blkHeight) 17 | 18 | if tileMode == 1: 19 | if roundPitch == 1: 20 | pitch = round_up(width * bpp, 32) 21 | else: 22 | pitch = width * bpp 23 | surfSize = round_up(pitch * height, 32) 24 | 25 | else: 26 | pitch = round_up(width * bpp, 64) 27 | surfSize = pitch * round_up(height, block_height * 8) 28 | 29 | result = bytearray(surfSize) 30 | 31 | for y in range(height): 32 | for x in range(width): 33 | if tileMode == 1: 34 | pos = y * pitch + x * bpp 35 | 36 | else: 37 | pos = getAddrBlockLinear(x, y, width, bpp, 0, block_height) 38 | 39 | pos_ = (y * width + x) * bpp 40 | 41 | if pos + bpp <= surfSize: 42 | if toSwizzle == 1: 43 | result[pos:pos + bpp] = data[pos_:pos_ + bpp] 44 | 45 | else: 46 | result[pos_:pos_ + bpp] = data[pos:pos + bpp] 47 | size = width * height * bpp 48 | return result[:size] 49 | 50 | 51 | def deswizzle(width, height, blkWidth, blkHeight, bpp, tileMode, size_range, data): 52 | return _swizzle(width, height, blkWidth, blkHeight, bpp, tileMode, size_range, bytes(data), 0) 53 | 54 | 55 | def swizzle(width, height, blkWidth, blkHeight, bpp, tileMode, size_range, data): 56 | return _swizzle(width, height, blkWidth, blkHeight, bpp, tileMode, size_range, bytes(data), 1) 57 | 58 | 59 | def getAddrBlockLinear(x, y, image_width, bytes_per_pixel, base_address, block_height): 60 | """ 61 | From the Tegra X1 TRM 62 | """ 63 | image_width_in_gobs = DIV_ROUND_UP(image_width * bytes_per_pixel, 64) 64 | 65 | GOB_address = (base_address 66 | + (y // (8 * block_height)) * 512 * block_height * image_width_in_gobs 67 | + (x * bytes_per_pixel // 64) * 512 * block_height 68 | + (y % (8 * block_height) // 8) * 512) 69 | 70 | x *= bytes_per_pixel 71 | 72 | Address = (GOB_address + ((x % 64) // 32) * 256 + ((y % 8) // 2) * 64 73 | + ((x % 32) // 16) * 32 + (y % 2) * 16 + (x % 16)) 74 | 75 | return Address 76 | -------------------------------------------------------------------------------- /tools/unpack_dat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import sys 4 | 5 | import argparse 6 | import os 7 | import shutil 8 | import format.dat as dat 9 | import unpack_dds 10 | 11 | 12 | def ensure_dir(output_dir): 13 | if os.path.isfile(output_dir): 14 | raise Exception("Unable to extract to " + output_dir + ": not a directory") 15 | if not os.path.isdir(output_dir): 16 | os.mkdir(output_dir) 17 | 18 | 19 | def unpack_dat(input_file, output_dir): 20 | ensure_dir(output_dir) 21 | with open(input_file, "rb") as file: 22 | archive = dat.File.parse(file) 23 | for f in archive.files: 24 | output_file = os.path.join(output_dir, f.name) 25 | with open(output_file, "wb") as out_file: 26 | out_file.write(f.bytes) 27 | if os.path.splitext(output_file)[1] == ".wtp": 28 | unpack_dds.unpack_wtp( 29 | output_file, 30 | output_file.replace(".wtp", ".wta").replace(".dtt", ".dat"), 31 | "", 32 | ) 33 | 34 | 35 | def unpack_dir(input_dir, output_dir, depth): 36 | if depth <= 0: 37 | return 38 | 39 | ensure_dir(output_dir) 40 | for entry in os.scandir(input_dir): 41 | if entry.is_dir(): 42 | unpack_dir(entry.path, os.path.join(output_dir, entry.name), depth - 1) 43 | elif os.path.splitext(entry.path)[1] != ".dtt": 44 | unpack_file(entry.path, output_dir) 45 | # to ensure textures are unpacked in preoper order (dat first, dtt second) 46 | for entry in os.scandir(input_dir): 47 | if entry.is_file() and os.path.splitext(entry.path)[1] == ".dtt": 48 | unpack_file(entry.path, output_dir) 49 | 50 | 51 | def unpack_file(input_file, output_dir): 52 | ensure_dir(output_dir) 53 | ext = os.path.splitext(input_file)[1] 54 | if ext in {".dat", ".dtt"} and os.path.getsize(input_file) > 0: 55 | unpack_dat(input_file, os.path.join(output_dir, os.path.basename(input_file))) 56 | else: 57 | shutil.copyfile( 58 | input_file, os.path.join(output_dir, os.path.basename(input_file)) 59 | ) 60 | 61 | 62 | if __name__ == "__main__": 63 | parser = argparse.ArgumentParser( 64 | description="Upacks .dat and .dtt files", 65 | formatter_class=argparse.RawDescriptionHelpFormatter, 66 | epilog=""" 67 | This tool will automatically unpack wta files 68 | 69 | Files will be placed into respecive directories, e.g. for following situation: 70 | 71 | ./dat/ 72 | abc.dat 73 | abc.dtt 74 | other.txt 75 | 76 | command `./unpack.py dat out` will create following directory structure: 77 | 78 | ./out/ 79 | abc.dat/ 80 | xyz.bin 81 | xyz.z 82 | xyz.wta 83 | abc.dtt/ 84 | xyz.wtp 85 | xyz.wtp_001.dds 86 | xyz.wtp_002.dds 87 | xyz.wtp_003.dds 88 | other.txt 89 | 90 | command `./unpack.py dat/abc.dat out` will create following directory structure: 91 | 92 | ./out/ 93 | xyz.bin 94 | xyz.z 95 | xyz.wta 96 | 97 | Please note that xyz.wta and xyz.wtp containing texture data will be extracted furher into xyz.wtp_00*.dds files 98 | """, 99 | ) 100 | parser.add_argument( 101 | "--depth", help="recursion depth (default=5)", default=5, type=int 102 | ) 103 | parser.add_argument("input", help="input file or directory") 104 | parser.add_argument("output", help="output directory") 105 | 106 | args = parser.parse_args() 107 | input = args.input 108 | output = args.output 109 | 110 | if os.path.isfile(output): 111 | raise Exception(output + " should be a directory") 112 | 113 | if os.path.isfile(input): 114 | unpack_file(input, output) 115 | elif os.path.isdir(input): 116 | unpack_dir(input, output, args.depth) 117 | else: 118 | raise Exception(input + " does not exist") 119 | -------------------------------------------------------------------------------- /tools/unpack_dds.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import argparse 4 | import os 5 | import format.wta as wta 6 | import swizzle 7 | 8 | 9 | def unpack_wtp(wtp_filename, wta_filename, out_dir=""): 10 | if not os.path.isfile(wtp_filename) or not os.path.isfile(wta_filename): 11 | return # skip if not exist 12 | with open(wta_filename, "rb") as wta_file: 13 | with open(wtp_filename, "rb") as wtp_file: 14 | parsed_wta = wta.File.parse(wta_file) 15 | for id, f in enumerate(parsed_wta.textures): 16 | out_filename = wtp_filename + "_" + str(id).zfill(3) + ".dds" 17 | if out_dir: 18 | out_filename = os.path.join(out_dir, os.path.basename(out_filename)) 19 | if f.is_astc(): 20 | out_filename = out_filename + ".astc" 21 | with open(out_filename, "wb") as out_file: 22 | wtp_file.seek(f.offset) 23 | content = wtp_file.read(f.size) 24 | if f.is_astc(): 25 | size_range = 4 if f.tex_height() >= 512 else 3 26 | content = f.astc_header() + swizzle.deswizzle( 27 | f.tex_width(), 28 | f.tex_height(), 29 | 6, 30 | 6, 31 | 16, 32 | 0, 33 | size_range, 34 | content, 35 | ) 36 | out_file.write(content) 37 | 38 | 39 | if __name__ == "__main__": 40 | parser = argparse.ArgumentParser() 41 | parser.add_argument("wta_file", help=".wta file name") 42 | parser.add_argument("wtp_file", help=".wtp file name") 43 | parser.add_argument("directory", help="output directory") 44 | 45 | args = parser.parse_args() 46 | unpack_wtp(args.wtp_file, args.wta_file, args.directory) 47 | -------------------------------------------------------------------------------- /tools/unpack_font.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import argparse 4 | import format.ftb as ftb 5 | import format.mcd as mcd 6 | from PIL import Image 7 | import os 8 | 9 | 10 | def ensure_dir(output_dir): 11 | if os.path.isfile(output_dir): 12 | raise Exception("Unable to extract to " + output_dir + ": not a directory") 13 | if not os.path.isdir(output_dir): 14 | os.makedirs(output_dir) 15 | 16 | 17 | if __name__ == "__main__": 18 | parser = argparse.ArgumentParser() 19 | parser.add_argument("--skip-cjk", help="skip CJK characters", action="store_true") 20 | parser.add_argument( 21 | "--font-id", help="font number (relevant for .mcd)", default=0, type=int 22 | ) 23 | parser.add_argument( 24 | "--char", help="extract only the character specified by code point", type=int 25 | ) 26 | parser.add_argument("font_file", help=".ftb or .mcd file name") 27 | parser.add_argument( 28 | "directory", help="output directory that will contain separated glyphs" 29 | ) 30 | parser.add_argument( 31 | "image_files", help="list of image file names (.dds or .png)", nargs="+" 32 | ) 33 | 34 | args = parser.parse_args() 35 | 36 | parsed = None 37 | ext = os.path.splitext(args.font_file)[1] 38 | if ext == ".ftb": 39 | parsed = ftb.File.parse(open(args.font_file, "rb")) 40 | if len(args.image_files) != parsed.header.textures_count: 41 | raise Exception( 42 | "Invalid number of image files: was {0}, expected {1}".format( 43 | len(args.image_files), parsed.header.textures_count 44 | ) 45 | ) 46 | elif ext == ".mcd": 47 | parsed = mcd.File.parse(open(args.font_file, "rb")) 48 | if len(args.image_files) != 1: 49 | raise Exception( 50 | "Invalid number of image files: was {0}, expected 1".format( 51 | len(args.image_files) 52 | ) 53 | ) 54 | else: 55 | raise Exception("Unknown file type for: " + args.font_file) 56 | 57 | textures = [] 58 | for img_file in args.image_files: 59 | textures.append(Image.open(img_file)) 60 | 61 | ensure_dir(args.directory) 62 | 63 | for char, glyph in parsed.get_glyphs(textures, args.font_id).items(): 64 | if args.char and args.char != ord(char): 65 | continue 66 | if args.skip_cjk and ( 67 | (ord(char) >= 0x2E80 and ord(char) <= 0x9FFF) 68 | or (ord(char) >= 0xAC00 and ord(char) <= 0xD7FF) 69 | ): 70 | continue 71 | outfile = os.path.join(args.directory, "{0:04x}.png".format(ord(char))) 72 | glyph.save(outfile) 73 | --------------------------------------------------------------------------------