├── pkg_menu.list ├── issue_template.md ├── tbb2shift.list ├── swap.sh ├── vcalcOpCodes.hh ├── patchEboot.py ├── transfer.sh ├── 1stload.list ├── 102repack_ch.sh ├── sceneTool.hh ├── Makefile ├── unplt.cpp ├── encScripts.sh ├── 102repack.sh ├── plt.cpp ├── tbbconv ├── node_modules │ └── jconv │ │ ├── package.json │ │ ├── READMEja.md │ │ ├── README.md │ │ ├── jconv.min.js │ │ └── jconv.js └── tbbconv.js ├── Translation.md ├── undat.cpp ├── README.md ├── xaiPatch.cpp ├── dat.cpp ├── unxai.cpp ├── sceneOpCodeNames.hh ├── LICENSE ├── xai.cpp ├── sceneOpCodes.hh ├── bin2script.cpp └── script2bin.cpp /pkg_menu.list: -------------------------------------------------------------------------------- 1 | 2 | dir_book.rsb 3 | #help.rsb CRASH 4 | item_dtt.rsb 5 | itwin.rsb 6 | itwins.rsb 7 | mdiary.rsb 8 | mopt.rsb 9 | -------------------------------------------------------------------------------- /issue_template.md: -------------------------------------------------------------------------------- 1 | ### YS VIII ### 2 | 3 | - 1 : Did you create your own or download a pre-patched ? 4 | 5 | - 2 : Are you using the latest version ? 6 | 7 | - 3 : Where does the bug occur ? (Please be specific with details) 8 | 9 | - 4 : Please provide a save. 10 | 11 | Thank you. 12 | -------------------------------------------------------------------------------- /tbb2shift.list: -------------------------------------------------------------------------------- 1 | #3dicon.tbb 2 | actev.tbb 3 | balance.tbb 4 | diary.tbb 5 | drchara.tbb 6 | #equip.tbb 7 | #fisharea.tbb 8 | #fishchar.tbb 9 | #fishchr2.tbb 10 | #fishhazu.tbb 11 | #fish.tbb 12 | invtable.tbb 13 | itempt.tbb 14 | item.tbb 15 | lensfl.tbb 16 | manual.tbb 17 | map3dcon.tbb 18 | #mapcoop.tbb 19 | #mapevent.tbb 20 | #mapmstbl.tbb 21 | mapname.tbb 22 | #mapopen.tbb 23 | maprange.tbb 24 | #mapwarp.tbb 25 | minimap.tbb 26 | mixitem2.tbb 27 | monslib.tbb 28 | npcparam.tbb 29 | #pc.tbb 30 | quest.tbb 31 | record.tbb 32 | #shop2.tbb 33 | #skill.tbb 34 | soundefx.tbb 35 | status.tbb 36 | #tips.tbb 37 | voice.tbb 38 | #vo_scene.tbb -------------------------------------------------------------------------------- /swap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | display_usage() 4 | { 5 | echo "Usage : $0 " 6 | echo -e " Copies the filenames in from to " 7 | } 8 | 9 | if [ $# -lt 3 ] 10 | then 11 | display_usage 12 | exit 1 13 | fi 14 | 15 | input=$2 16 | output=$3 17 | 18 | while IFS='' read -r filename || [[ -n "$filename" ]]; do 19 | 20 | [[ "$filename" =~ ^#.*$ ]] && continue 21 | [[ -z "$filename" ]] && continue 22 | 23 | if [ $1 = tbb2shift.list ]; then 24 | echo "Converting $filename from $input to $output as SHIFT-JIS" 25 | 26 | node tbbconv/tbbconv.js unpack "$input"/"$filename" tmp 27 | node tbbconv/tbbconv.js pack tmp "$output"/"$filename" --enc shift-jis 28 | # mkdir -p tbb 29 | # cp tmp tbb/"$filename".csv 30 | 31 | else 32 | echo "Copying $filename from $input to $output" 33 | cp -f "$input"/"$filename" "$output"/"$filename" 34 | fi 35 | 36 | done < "$1" 37 | 38 | echo "Script $1 finished" 39 | 40 | -------------------------------------------------------------------------------- /vcalcOpCodes.hh: -------------------------------------------------------------------------------- 1 | // Scene OpCodes 2 | 3 | #pragma once 4 | 5 | enum VCalcOpCode { 6 | 7 | VCODE_NEQ = 0x0001, 8 | VCODE_NOT = 0x0002, 9 | VCODE_MUL = 0x0003, 10 | VCODE_DIV = 0x0004, 11 | VCODE_IDIV = 0x0005, 12 | VCODE_ADD = 0x0006, 13 | VCODE_SUB = 0x0007, 14 | VCODE_SRL = 0x0008, 15 | VCODE_GE = 0x0009, 16 | VCODE_GT = 0x000A, 17 | VCODE_SLL = 0x000B, 18 | VCODE_LE = 0x000C, 19 | VCODE_LT = 0x000D, 20 | VCODE_EQ = 0x000E, 21 | VCODE_AND = 0x0010, 22 | VCODE_BAND = 0x0011, 23 | VCODE_OR = 0x0012, 24 | VCODE_BOR = 0x0013, 25 | VCODE_BNOT = 0x0014, 26 | VCODE_XOR = 0x0015, 27 | VCODE_LDINT = 0x001A, 28 | VCODE_LDFLT = 0x001B, 29 | VCODE_LDGLB = 0x001C, 30 | VCODE_END = 0x001D, 31 | VCODE_LDVAR = 0x001F, 32 | 33 | VCODE_NOP = 0x0024, 34 | VCODE_ABS = 0x0025, 35 | VCODE_F2I = 0x0026, 36 | VCODE_I2F = 0x0027, 37 | VCODE_RAND = 0x0029, 38 | VCODE_FRAND = 0x002A, 39 | VCODE_SOBJ = 0x002C, 40 | VCODE_ROBJ = 0x002B, 41 | 42 | VCODE_NEG = 0x0042, 43 | 44 | VCODE_MAXVAL = 0x0045 45 | }; 46 | -------------------------------------------------------------------------------- /patchEboot.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | from io import * 4 | import sys 5 | 6 | saveLvlPatch0="Lv %d\0\0" 7 | saveLvlPatch1="Lv %d\n\0" 8 | saveLvlOrigin="Lv%02d" 9 | bSaveLvlOrigin=bytes(saveLvlOrigin, 'utf8') 10 | 11 | # Patch the eboot's save level formatting 12 | def patchEboot(path): 13 | try: 14 | with open(path, 'r+b') as fh: 15 | print('Patching ' + path + ' ...') 16 | data = fh.read() 17 | offset0 = data.find(bSaveLvlOrigin) 18 | offset1 = data.find(bSaveLvlOrigin, offset0 + len(saveLvlOrigin)) 19 | 20 | if offset0 > 1000 and offset1 > 1000: 21 | print('First offset : ' + hex(offset0)) 22 | print('Second offset : ' + hex(offset1)) 23 | 24 | fh.seek(offset0) 25 | fh.write(bytes(saveLvlPatch0, 'utf8')) 26 | fh.seek(offset1) 27 | fh.write(bytes(saveLvlPatch1, 'utf8')) 28 | print(path + ' patched') 29 | 30 | else: 31 | print("File does not require patching") 32 | 33 | except IOError: 34 | print(path + ' not found') 35 | 36 | 37 | if __name__ == "__main__": 38 | patchEboot(sys.argv[1]) 39 | -------------------------------------------------------------------------------- /transfer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR=$1 4 | 5 | #cp -f patch101_fix.xai $DIR/app/PCSG00881/patch101.xai 6 | cp -f patch102_fix.xai $DIR/app/PCSG00881/patch102.xai 7 | # cp -f patch102_fix_ch.xai $DIR/app/PCSH00297/patch102.xai 8 | 9 | # ./xaiPatch patch101_fix.xai "shift-jis_dist/patch101/script/mp1201.bin" script/mp1201.bin 10 | # ./xaiPatch $DIR/app/PCSG00881/patch101.xai "shift-jis_dist/patch101/script/mp1201.bin" script/mp1201.bin 11 | 12 | # ./xaiPatch $DIR/app/PCSG00881/rootast.xai "jap/base/movie/logo.mp4" movie/logo.mp4 13 | 14 | # for script in script/*; do 15 | # ./xaiPatch $DIR/app/PCSG00881/rootast.xai $script $script > /dev/null 16 | # done 17 | 18 | #./xaiPatch $DIR/app/PCSG00881/rootast.xai custom/mp4102t2.bin script/mp4102t2.bin 19 | 20 | ./patchEboot.py $DIR/app/PCSG00881/eboot.bin 21 | ./patchEboot.py $DIR/app/PCSG00881/mai_moe/eboot_origin.bin 22 | 23 | # ./patchEboot.py $DIR/app/PCSH00297/eboot.bin > /dev/null 24 | # ./patchEboot.py $DIR/app/PCSH00297/mai_moe/eboot_origin.bin > /dev/null 25 | 26 | 27 | echo "Unmounting '${DIR}', please wait ..." 28 | umount $DIR -v 29 | -------------------------------------------------------------------------------- /1stload.list: -------------------------------------------------------------------------------- 1 | #3dicon.h OK 2 | 3dicon.tbb 3 | actev.tbb 4 | #argpunc.txt <= CRASH 5 | ascii2l.itp 6 | balance.tbb 7 | c000.mtb 8 | c001.mtb 9 | #c002.mtb One of those bugs laxia's finisher, other .mtb only changed smthg like checksum 10 | c003.mtb 11 | #c004.mtb One of those bugs laxia's finisher, other .mtb only changed smthg like checksum 12 | c005.mtb 13 | #def.h OK 14 | diary.tbb 15 | drchara.tbb 16 | #efxlist.txt OK 17 | #enum_al.h OK 18 | #enum_rl.h OK 19 | equip.tbb 20 | fisharea.tbb 21 | fishchar.tbb 22 | fishchr2.tbb 23 | #fish.h OK 24 | fishhazu.tbb 25 | fish.tbb 26 | #flag.h OK 27 | font.itf 28 | #inccc2.scp 29 | #inccc3.scp 30 | #inccc.scp 31 | invtable.tbb 32 | item.bin 33 | itempt.tbb 34 | item.tbb 35 | lensfl.tbb 36 | lit_atxt.csv 37 | #lit_rtxt.csv BUG : Can't move, but has english stuff 38 | manual.tbb 39 | map3dcon.tbb 40 | mapainfo.tlb 41 | mapcoop.tbb 42 | mapevent.tbb 43 | mapmstbl.tbb 44 | mapname.tbb 45 | mapopen.tbb 46 | maprange.tbb 47 | mapwarp.tbb 48 | minimap.tbb 49 | mixitem2.tbb 50 | #mons.h CRASH 51 | monslib.tbb 52 | #monspunc.txt OK 53 | #mtdpunc.txt TODO : TEST 54 | npc.bin 55 | npcparam.tbb 56 | #opepunc.txt CRASH 57 | pc.tbb 58 | pl_const.plt 59 | quest.tbb 60 | record.tbb 61 | #rszpunc.txt TODO : TEST 62 | #scr_inc.h TODO : TEST 63 | #scr_punc.txt TODO : TEST 64 | #se.h TODO : TEST 65 | shdlist.csv 66 | shop2.tbb 67 | #skilldef.h TODO : TEST 68 | skill.tbb 69 | soundefx.tbb 70 | # status.tbb bugs on the japanese game, so we have to reencode it later for this game 71 | status.tbb 72 | system.bin 73 | system01.itp 74 | talk.bin 75 | talkcam.bin 76 | #tips.h TODO : TEST 77 | tips.tbb 78 | #vo.h TODO : TEST 79 | voice.tbb 80 | vo_scene.tbb 81 | y8_btl.itp 82 | -------------------------------------------------------------------------------- /102repack_ch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PKG_MENU_ENG_DIR=pkg_menu_eng 4 | PKG_MENU_FIX_DIR=pkg_menu_fix_ch 5 | PKG_MENU_CH_XAI=pkg_menu_ch.xai 6 | PKG_MENU_OUT=pkg_menu_fix_ch.xai 7 | PKG_MENU_LIST=pkg_menu.list 8 | 9 | PATCH_102_FIX_DIR=patch102_fix_ch 10 | PATCH_102_REAL=patch102_real_ch.xai 11 | PATCH_102_OUT=patch102_fix_ch.xai 12 | 13 | DAT_CH=1stload_ch.dat 14 | DAT_FIX_DIR=1stload_fix_ch 15 | DAT_OUT=1stload_fix_ch.dat 16 | 17 | DAT_LIST=1stload.list 18 | DAT_ENG_DIR=1stload_allEng 19 | 20 | TBB_LIST=tbb2shift.list 21 | 22 | 23 | rm $PKG_MENU_FIX_DIR/* 24 | ./unxai $PKG_MENU_CH_XAI $PKG_MENU_FIX_DIR > /dev/null 25 | ./swap.sh $PKG_MENU_LIST $PKG_MENU_ENG_DIR $PKG_MENU_FIX_DIR > /dev/null 26 | 27 | ./xai $PKG_MENU_FIX_DIR $PKG_MENU_OUT $PKG_MENU_CH_XAI > /dev/null 28 | cp -f $PKG_MENU_OUT $PATCH_102_FIX_DIR/flash/pkg_menu.xai 29 | 30 | rm $DAT_FIX_DIR/* 31 | ./undat $DAT_CH $DAT_FIX_DIR > /dev/null 32 | ./swap.sh $DAT_LIST $DAT_ENG_DIR $DAT_FIX_DIR > /dev/null 33 | 34 | cp -f custom/lit_rtxt_ch.csv $DAT_FIX_DIR/lit_rtxt.csv 35 | cp -f custom/lit_rtxt_ch.csv $PATCH_102_FIX_DIR/system/lit_rtxt.csv 36 | 37 | cp -f custom/pl_const_ch.plt $DAT_FIX_DIR/pl_const.plt 38 | cp -f custom/pl_const_ch.plt $PATCH_102_FIX_DIR/flash/pl_const.plt 39 | 40 | 41 | # mkdir -p tbb 42 | # ./swap.sh $TBB_LIST $DAT_ENG_DIR tbb > /dev/null 43 | 44 | cp -f tbb_utf8/* $DAT_FIX_DIR 45 | 46 | 47 | ./dat $DAT_FIX_DIR $DAT_OUT > /dev/null 48 | cp -f $DAT_OUT $PATCH_102_FIX_DIR/system/1stload.dat 49 | 50 | ./xai $PATCH_102_FIX_DIR $PATCH_102_OUT $PATCH_102_REAL > /dev/null 51 | cp -f $PATCH_102_OUT patch102.xai 52 | 53 | # Some checks 54 | diff $PATCH_102_FIX_DIR/flash/pkg_menu.xai $PKG_MENU_OUT 55 | diff $PATCH_102_FIX_DIR/system/1stload.dat $DAT_OUT 56 | -------------------------------------------------------------------------------- /sceneTool.hh: -------------------------------------------------------------------------------- 1 | // Scene tool 2 | 3 | #pragma once 4 | #include 5 | 6 | struct __attribute__((__packed__)) FILE_HEADER_V2 { 7 | char magic[8]; //"YS7_SCP\0" 8 | uint8_t reserved[3]; //Isn't accessed by implementation 9 | uint8_t version; //0x4 in mine, 0x2-0x4 use V2 header 10 | uint64_t checksum; //Doesn't appear to be checked by loader 11 | uint32_t segs_count; //Segments count 12 | // SEGMENT_HEADER[segs_count] segments; //Segment headers 13 | }; 14 | 15 | struct __attribute__((__packed__)) SEGMENT_HEADER { 16 | char name[0x20]; //Segment name 17 | uint32_t size; //Size of segment data 18 | uint32_t offset; //Offset to segment data from the beginning of file 19 | }; 20 | 21 | typedef uint16_t OPCODE; 22 | typedef uint16_t DATA_TAG; 23 | 24 | enum DataTag { 25 | 26 | INT_TAG = 0x82DD, 27 | FLOAT_TAG = 0x82DE, 28 | STRING_TAG = 0x82DF, 29 | VCALC_TAG = 0x82E0, 30 | 31 | POPUP_TAG = 0x2020, 32 | }; 33 | 34 | 35 | struct __attribute__((__packed__)) GENERIC_ARG { 36 | 37 | uint16_t tag; 38 | 39 | union __attribute__((__packed__)) { 40 | int32_t iVal; 41 | float fVal; 42 | uint32_t uVal; 43 | }; 44 | }; 45 | 46 | 47 | struct __attribute__((__packed__)) INT_ARG { 48 | uint16_t tag_82DD; 49 | int32_t value; 50 | }; 51 | 52 | struct __attribute__((__packed__)) FLOAT_ARG { 53 | uint16_t tag_82DE; 54 | float value; 55 | }; 56 | 57 | struct __attribute__((__packed__)) STRING_ARG { 58 | uint16_t tag_82DF; 59 | uint32_t cch; 60 | // char[cch] text; 61 | }; 62 | 63 | struct __attribute__((__packed__)) VCALC_ARG { 64 | uint16_t tag_82E0; 65 | uint32_t length; 66 | // uint8_t[length] value; 67 | }; 68 | 69 | struct __attribute__((__packed__)) POPUP_ARG { 70 | uint16_t tag_2020; 71 | uint32_t nLines; 72 | uint32_t len; 73 | // uint16_t[nLines] linePositions? 74 | // char[len] popupText 75 | }; 76 | 77 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | INC= 3 | LIB= 4 | LSUFFIX= 5 | 6 | CCFLAGS=-std=c++11 -g 7 | 8 | ifeq ($(OS),Windows_NT) 9 | CCFLAGS += -D WIN32 -static -static-libgcc -static-libstdc++ 10 | INC=C:\Program Files\boost\include\boost-1_65_1 11 | LIB=C:\Program Files\boost\lib 12 | LSUFFIX=-mgw48-mt-1_65_1 13 | 14 | ifeq ($(PROCESSOR_ARCHITEW6432),AMD64) 15 | CCFLAGS += -D AMD64 16 | else 17 | ifeq ($(PROCESSOR_ARCHITECTURE),AMD64) 18 | CCFLAGS += -D AMD64 19 | endif 20 | ifeq ($(PROCESSOR_ARCHITECTURE),x86) 21 | CCFLAGS += -D IA32 22 | endif 23 | endif 24 | else 25 | UNAME_S := $(shell uname -s) 26 | ifeq ($(UNAME_S),Linux) 27 | CCFLAGS += -D LINUX 28 | endif 29 | ifeq ($(UNAME_S),Darwin) 30 | CCFLAGS += -D OSX 31 | endif 32 | UNAME_P := $(shell uname -p) 33 | ifeq ($(UNAME_P),x86_64) 34 | CCFLAGS += -D AMD64 35 | endif 36 | ifneq ($(filter %86,$(UNAME_P)),) 37 | CCFLAGS += -D IA32 38 | endif 39 | ifneq ($(filter arm%,$(UNAME_P)),) 40 | CCFLAGS += -D ARM 41 | endif 42 | endif 43 | 44 | IFLAGS=-I"${INC}" 45 | LFLAGS=-L"${LIB}" -lboost_system${LSUFFIX} -lboost_filesystem${LSUFFIX} -lboost_locale${LSUFFIX} 46 | 47 | all: xai unxai dat undat plt unplt xaiPatch bin2script script2bin 48 | 49 | xai: xai.cpp 50 | g++ ${CCFLAGS} -o $@ $< ${IFLAGS} ${LFLAGS} 51 | 52 | unxai: unxai.cpp 53 | g++ ${CCFLAGS} -o $@ $< ${IFLAGS} ${LFLAGS} 54 | 55 | dat: dat.cpp 56 | g++ ${CCFLAGS} -o $@ $< ${IFLAGS} ${LFLAGS} 57 | 58 | undat: undat.cpp 59 | g++ ${CCFLAGS} -o $@ $< ${IFLAGS} ${LFLAGS} 60 | 61 | plt: plt.cpp 62 | g++ ${CCFLAGS} -o $@ $< 63 | 64 | unplt: unplt.cpp 65 | g++ ${CCFLAGS} -o $@ $< 66 | 67 | xaiPatch: xaiPatch.cpp 68 | g++ ${CCFLAGS} -o $@ $< 69 | 70 | bin2script: bin2script.cpp sceneTool.hh sceneOpCodes.hh sceneOpCodeNames.hh 71 | g++ ${CCFLAGS} -fpermissive -o $@ $< ${IFLAGS} ${LFLAGS} 72 | 73 | script2bin: script2bin.cpp sceneTool.hh sceneOpCodes.hh sceneOpCodeNames.hh 74 | g++ ${CCFLAGS} -fpermissive -o $@ $< ${IFLAGS} ${LFLAGS} 75 | 76 | 77 | clean: 78 | rm unxai xai -f 79 | rm undat dat -f 80 | rm unplt plt -f 81 | rm xaiPatch -f 82 | rm bin2script -f 83 | rm script2bin -f 84 | -------------------------------------------------------------------------------- /unplt.cpp: -------------------------------------------------------------------------------- 1 | // PLT Unpacker by yosh778 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | uint16_t read16(std::ifstream& input) { 12 | uint16_t data; 13 | input.read((char*)&data, (int)sizeof(data)); 14 | return data; 15 | } 16 | 17 | uint32_t read32(std::ifstream& input) { 18 | uint32_t data; 19 | input.read((char*)&data, (int)sizeof(data)); 20 | return data; 21 | } 22 | 23 | uint64_t read64(std::ifstream& input) { 24 | uint64_t data; 25 | input.read((char*)&data, (int)sizeof(data)); 26 | return data; 27 | } 28 | 29 | int main(int argc, char *argv[]) 30 | { 31 | if ( argc < 3 ) { 32 | std::cerr << "Usage : " << argv[0] << " " << std::endl; 33 | return -1; 34 | } 35 | 36 | std::string iDir = argv[1]; 37 | std::string oDir = argv[2]; 38 | 39 | std::ifstream file( iDir.c_str(), std::ios_base::binary ); 40 | 41 | if ( !file.is_open() ) 42 | return -2; 43 | 44 | uint32_t data; 45 | 46 | uint16_t nbEntries = read16(file); 47 | char fileName[64]; 48 | 49 | uint8_t *buf = NULL; 50 | uint16_t bufSize = 0; 51 | uint32_t nFoundEntries = 0; 52 | 53 | std::ofstream output( oDir.c_str(), std::ios_base::trunc ); 54 | 55 | if ( !output.is_open() ) 56 | return -1; 57 | 58 | 59 | for (uint32_t i = 0; i < nbEntries; i++) { 60 | 61 | file.read(fileName, sizeof(fileName)); 62 | fileName[63] = 0; 63 | 64 | std::cout << fileName << std::endl; 65 | 66 | uint16_t size = read16(file); 67 | 68 | if ( !size ) 69 | continue; 70 | 71 | nFoundEntries++; 72 | 73 | if ( (size+1) > bufSize ) { 74 | buf = (uint8_t*)realloc( buf, size+1 ); 75 | bufSize = size+1; 76 | } 77 | 78 | file.read( (char*)buf, size ); 79 | buf[size] = 0; 80 | 81 | output << fileName << std::endl; 82 | output << buf << std::endl; 83 | } 84 | 85 | output.close(); 86 | 87 | std::cerr << 88 | std::endl << "Number of declared entries : " << nbEntries << std::endl; 89 | std::cerr << "Number of extracted entries : " << nFoundEntries << std::endl; 90 | 91 | file.close(); 92 | 93 | return 0; 94 | } 95 | 96 | -------------------------------------------------------------------------------- /encScripts.sh: -------------------------------------------------------------------------------- 1 | 2 | 3 | clear 4 | clear 5 | 6 | rm -rf "shift-jis_dist/" 7 | 8 | DIR="shift-jis_dist" 9 | 10 | mkdir -p $DIR 11 | 12 | 13 | for path in eng/*/script/*; do 14 | ./bin2script "$path" 2>err > tmp 15 | exit_status=$? 16 | cat err | grep -v "Invalid" 17 | 18 | if [ $exit_status -eq 0 ]; then 19 | PREV="${path%%/*}" 20 | NEXT="${path#*/}" 21 | DEST="${PREV}_enc/${NEXT}" 22 | ./script2bin tmp "$DEST" --enc-shift-jis > /dev/null 23 | # ./bin2script "$DEST" > mm 2>err 24 | # ./script2bin mm nn > /dev/null 25 | # echo $path 26 | fi 27 | done 28 | 29 | mv "${PREV}_enc" "$DIR" 30 | 31 | 32 | for path in 1stload_allEng_script/*; do 33 | ./bin2script "$path" 2>err > tmp 34 | exit_status=$? 35 | cat err | grep -v "Invalid" 36 | 37 | if [ $exit_status -eq 0 ]; then 38 | PREV="${path%%/*}" 39 | NEXT="${path#*/}" 40 | DEST="${PREV}_enc/${NEXT}" 41 | ./script2bin tmp "$DEST" --enc-shift-jis > /dev/null 42 | # echo $path 43 | fi 44 | done 45 | 46 | mv "${PREV}_enc" "$DIR" 47 | 48 | 49 | for path in patch102_eng/script/*; do 50 | ./bin2script "$path" 2>err > tmp 51 | exit_status=$? 52 | cat err | grep -v "Invalid" 53 | 54 | if [ $exit_status -eq 0 ]; then 55 | PREV="${path%%/*}" 56 | NEXT="${path#*/}" 57 | DEST="${PREV}_enc/${NEXT}" 58 | ./script2bin tmp "$DEST" --enc-shift-jis > /dev/null 59 | # echo $path 60 | fi 61 | done 62 | 63 | mv "${PREV}_enc" "$DIR" 64 | 65 | 66 | for path in sceneFixes/*; do 67 | ./bin2script "$path" 2>err > tmp 68 | exit_status=$? 69 | cat err | grep -v "Invalid" 70 | 71 | if [ $exit_status -eq 0 ]; then 72 | PREV="${path%%/*}" 73 | NEXT="${path#*/}" 74 | DEST="${PREV}_enc/${NEXT}" 75 | ./script2bin tmp "$DEST" --enc-shift-jis > /dev/null 76 | # echo $path 77 | fi 78 | done 79 | 80 | mv "${PREV}_enc" "$DIR" 81 | 82 | cp -f "$DIR"/sceneFixes_enc/mp4102t2.bin "$DIR"/eng_enc/base/script/mp4102t2.bin 83 | cp -f "$DIR"/sceneFixes_enc/mp1103.bin "$DIR"/patch102_eng_enc/script/mp1103.bin 84 | 85 | 86 | rm -rf "$DIR"/eng_enc/text_fr/ "$DIR"/eng_enc/patch102_fake 87 | 88 | mv "$DIR"/eng_enc/* "$DIR" 89 | mv "$DIR"/base "$DIR"/rootast 90 | rmdir "$DIR"/eng_enc 91 | 92 | -------------------------------------------------------------------------------- /102repack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PKG_MENU_ENG_DIR=pkg_menu_eng 4 | PKG_MENU_FIX_DIR=pkg_menu_fix 5 | PKG_MENU_JP_XAI=pkg_menu_jp.xai 6 | PKG_MENU_OUT=pkg_menu_fix.xai 7 | PKG_MENU_LIST=pkg_menu.list 8 | 9 | PATCH_102_FIX_DIR=patch102_fix 10 | PATCH_102_REAL=patch102_real.xai 11 | PATCH_102_OUT=patch102_fix.xai 12 | 13 | DAT_JP=1stload_jp.dat 14 | DAT_FIX_DIR=1stload_fix 15 | DAT_OUT=1stload_fix.dat 16 | 17 | DAT_LIST=1stload.list 18 | DAT_ENG_DIR=1stload_allEng 19 | 20 | TBB_LIST=tbb2shift.list 21 | 22 | 23 | rm $PKG_MENU_FIX_DIR/* 24 | ./unxai $PKG_MENU_JP_XAI $PKG_MENU_FIX_DIR > /dev/null 25 | ./swap.sh $PKG_MENU_LIST $PKG_MENU_ENG_DIR $PKG_MENU_FIX_DIR > /dev/null 26 | 27 | ./xai $PKG_MENU_FIX_DIR $PKG_MENU_OUT $PKG_MENU_JP_XAI > /dev/null 28 | cp -f $PKG_MENU_OUT $PATCH_102_FIX_DIR/flash/pkg_menu.xai 29 | 30 | rm $DAT_FIX_DIR/* 31 | ./undat $DAT_JP $DAT_FIX_DIR > /dev/null 32 | ./swap.sh $DAT_LIST $DAT_ENG_DIR $DAT_FIX_DIR > /dev/null 33 | 34 | cp -f custom/lit_rtxt.csv $DAT_FIX_DIR 35 | cp -f custom/lit_rtxt.csv $PATCH_102_FIX_DIR/system/lit_rtxt.csv 36 | 37 | cp -f custom/pl_const.plt $DAT_FIX_DIR 38 | cp -f custom/pl_const.plt $PATCH_102_FIX_DIR/flash/pl_const.plt 39 | 40 | cp -f custom/mp1103.bin $PATCH_102_FIX_DIR/script/mp1103.bin 41 | 42 | 43 | # ./script2bin custom/item_test.ys custom/item.bin --enc-shift-jis > /dev/null 44 | # ./script2bin custom/talk.ys custom/talk.bin --enc-shift-jis > /dev/null 45 | ./script2bin custom/mp1204_credits.ys custom/mp1204.bin --enc-shift-jis > /dev/null 46 | ./script2bin custom/mp1101_mod.ys custom/mp1101.bin --enc-shift-jis > /dev/null 47 | #./script2bin custom/talk_test.ys custom/talk.bin > /dev/null 48 | 49 | cp -f custom/mp1204.bin $PATCH_102_FIX_DIR/script/mp1204.bin 50 | #cp -f custom/mp1101.bin $PATCH_102_FIX_DIR/script/mp1101.bin 51 | 52 | #cp -f custom/item_fix.bin custom/item.bin 53 | 54 | 55 | # cp -f custom/item.bin $DAT_FIX_DIR 56 | #cp -f custom/talk.bin $DAT_FIX_DIR 57 | 58 | # mkdir -p tbb 59 | # ./swap.sh $TBB_LIST $DAT_ENG_DIR tbb > /dev/null 60 | 61 | cp -f tbb/* $DAT_FIX_DIR 62 | 63 | 64 | ./dat $DAT_FIX_DIR $DAT_OUT > /dev/null 65 | cp -f $DAT_OUT $PATCH_102_FIX_DIR/system/1stload.dat 66 | 67 | ./xai $PATCH_102_FIX_DIR $PATCH_102_OUT $PATCH_102_REAL > /dev/null 68 | cp -f $PATCH_102_OUT patch102.xai 69 | 70 | # Some checks 71 | diff $PATCH_102_FIX_DIR/flash/pkg_menu.xai $PKG_MENU_OUT 72 | diff $PATCH_102_FIX_DIR/system/1stload.dat $DAT_OUT 73 | 74 | -------------------------------------------------------------------------------- /plt.cpp: -------------------------------------------------------------------------------- 1 | // PLT Packer by yosh778 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | 13 | void write32(std::fstream& output, uint32_t data) { 14 | output.write((char*)&data, (int)sizeof(data)); 15 | } 16 | 17 | void write16(std::fstream& output, uint16_t data) { 18 | output.write((char*)&data, (int)sizeof(data)); 19 | } 20 | 21 | uint64_t write64(std::fstream& output, uint64_t data) { 22 | output.write((char*)&data, (int)sizeof(data)); 23 | } 24 | 25 | uint32_t read32(std::ifstream& input) { 26 | uint32_t data; 27 | input.read((char*)&data, (int)sizeof(data)); 28 | return data; 29 | } 30 | 31 | uint64_t read64(std::ifstream& input) { 32 | uint64_t data; 33 | input.read((char*)&data, (int)sizeof(data)); 34 | return data; 35 | } 36 | 37 | int main(int argc, char *argv[]) 38 | { 39 | if ( argc < 3 ) { 40 | std::cerr << "Usage : " << argv[0] << " " << std::endl; 41 | return -1; 42 | } 43 | 44 | std::string inPath = argv[1]; 45 | std::string output = argv[2]; 46 | uint32_t mimicUnused = 0; 47 | 48 | uint32_t i = 0; 49 | uint32_t nbEntries = 0; 50 | 51 | std::ifstream input( inPath.c_str() ); 52 | 53 | if ( !input.is_open() ) { 54 | std::cerr << "Failed to open " << inPath << std::endl; 55 | return -2; 56 | } 57 | 58 | std::fstream oFile( output.c_str(), std::ios_base::trunc | std::ios_base::out | std::ios_base::binary ); 59 | 60 | if ( !oFile.is_open() ) { 61 | std::cerr << "Failed to open output file '" << output << "'" << std::endl; 62 | return -2; 63 | } 64 | 65 | write16(oFile, nbEntries); 66 | 67 | i = 0; 68 | char nameBuf[64]; 69 | 70 | for( std::string line; getline( input, line ); ) 71 | { 72 | memset(nameBuf, 0, sizeof(nameBuf)); 73 | strncpy(nameBuf, line.c_str(), sizeof(nameBuf)-1); 74 | 75 | oFile.write( nameBuf, sizeof(nameBuf) ); 76 | 77 | std::cerr << "Writing " << nameBuf << std::endl; 78 | 79 | getline( input, line ); 80 | write16(oFile, line.size() ); 81 | oFile.write( line.c_str(), line.size() ); 82 | 83 | nbEntries++; 84 | } 85 | 86 | oFile.seekg(0); 87 | write16(oFile, nbEntries); 88 | 89 | input.close(); 90 | oFile.close(); 91 | 92 | std::cerr << nbEntries << " files were included" << std::endl; 93 | std::cerr << "PLT archive successfully created" << std::endl; 94 | 95 | return 0; 96 | } 97 | 98 | -------------------------------------------------------------------------------- /tbbconv/node_modules/jconv/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_args": [ 3 | [ 4 | { 5 | "raw": "jconv", 6 | "scope": null, 7 | "escapedName": "jconv", 8 | "name": "jconv", 9 | "rawSpec": "", 10 | "spec": "latest", 11 | "type": "tag" 12 | }, 13 | "E:\\GPs\\ys8\\status.tbb" 14 | ] 15 | ], 16 | "_from": "jconv@latest", 17 | "_id": "jconv@0.1.5", 18 | "_inCache": true, 19 | "_installable": true, 20 | "_location": "/jconv", 21 | "_npmUser": { 22 | "name": "narirou", 23 | "email": "narirou.github@gmail.com" 24 | }, 25 | "_npmVersion": "1.3.24", 26 | "_phantomChildren": {}, 27 | "_requested": { 28 | "raw": "jconv", 29 | "scope": null, 30 | "escapedName": "jconv", 31 | "name": "jconv", 32 | "rawSpec": "", 33 | "spec": "latest", 34 | "type": "tag" 35 | }, 36 | "_requiredBy": [ 37 | "#USER" 38 | ], 39 | "_resolved": "https://registry.npmjs.org/jconv/-/jconv-0.1.5.tgz", 40 | "_shasum": "c650edba4cc2ce6dd292bf3910b123433c4b47f5", 41 | "_shrinkwrap": null, 42 | "_spec": "jconv", 43 | "_where": "E:\\GPs\\ys8\\status.tbb", 44 | "auther": "narirou ", 45 | "bugs": { 46 | "url": "https://github.com/narirou/jconv/issues" 47 | }, 48 | "dependencies": {}, 49 | "description": "Pure JavaScript Iconv for Japanese encodings. (Shift_JIS, ISO-2022-JP, EUC-JP, UTF-8, UCS-2)", 50 | "devDependencies": { 51 | "async": "*", 52 | "benchmark": "*", 53 | "grunt": "~0.4.2", 54 | "grunt-closurecompiler": "*", 55 | "grunt-mocha-test": "*", 56 | "iconv": "*", 57 | "should": "*" 58 | }, 59 | "directories": {}, 60 | "dist": { 61 | "shasum": "c650edba4cc2ce6dd292bf3910b123433c4b47f5", 62 | "tarball": "https://registry.npmjs.org/jconv/-/jconv-0.1.5.tgz" 63 | }, 64 | "engines": { 65 | "node": ">=0.8.0" 66 | }, 67 | "homepage": "https://github.com/narirou/jconv", 68 | "keywords": [ 69 | "iconv", 70 | "encode", 71 | "encoding", 72 | "charset", 73 | "japanese" 74 | ], 75 | "license": "MIT", 76 | "main": "jconv.js", 77 | "maintainers": [ 78 | { 79 | "name": "narirou", 80 | "email": "narirou.github@gmail.com" 81 | } 82 | ], 83 | "name": "jconv", 84 | "optionalDependencies": {}, 85 | "readme": "ERROR: No README data found!", 86 | "repository": { 87 | "type": "git", 88 | "url": "git+https://github.com/narirou/jconv.git" 89 | }, 90 | "scripts": { 91 | "test": "grunt test" 92 | }, 93 | "version": "0.1.5" 94 | } 95 | -------------------------------------------------------------------------------- /tbbconv/node_modules/jconv/READMEja.md: -------------------------------------------------------------------------------- 1 | jconv 2 | ==================== 3 | 4 | > Pure JavaScript Iconv for Japanese encodings. 5 | 6 | [![Build Status](https://secure.travis-ci.org/narirou/jconv.png?branch=master)](https://travis-ci.org/narirou/jconv) 7 | [![NPM version](https://badge.fury.io/js/jconv.png)](http://badge.fury.io/js/jconv) 8 | 9 | * *Shift_JIS(CP932)、ISO-2022-JP(-1)、EUC-JP、UTF8、UNICODE* の相互変換を行うモジュールです。 10 | * JavaScriptのみで書かれているため、コンパイルは必要ありません。 11 | * [node-iconv](https://github.com/bnoordhuis/node-iconv)よりも高速に変換を行います。 12 | 13 | ## インストール 14 | ```bash 15 | $ npm install jconv 16 | ``` 17 | 18 | ## 使い方 19 | **EUC-JP** から **Shift_JIS** に変換したい場合は、次のようにします。 20 | 21 | ```javascript 22 | var jconv = require( 'jconv' ); 23 | 24 | var SJISBuffer = jconv.convert( EUCJPBuffer, 'EUCJP', 'SJIS' ); 25 | ``` 26 | 27 | **iconv-lite** 形式のAPIも利用可能です。 28 | 29 | ```javascript 30 | var str = jconv.decode( buffer, fromEncoding ); 31 | 32 | var buf = jconv.encode( 'string', toEncoding ); 33 | ``` 34 | 35 | ## API 36 | * **jconv( input, fromEncoding, toEncoding )** 37 | * **jconv.convert( input, fromEncoding, toEncoding )** 38 | * `input` {Buffer} または {String} 39 | * `fromEncoding`, `toEncoding` {String}: 40 | 変換元のエンコードと、変換先のエンコードを指定します。 41 | *Shift_JIS(SJIS,CP932)、ISO-2022-JP(JIS)、EUCJP、UTF8、UNICODE(UCS2,UTF16LE)* のいずれかを指定してください。 42 | * `return` {Buffer} 43 | 44 | * **jconv.decode( inputBuffer, fromEncoding )** 45 | * `return` {String} 46 | 47 | * **jconv.encode( inputString, toEncoding )** 48 | * `return` {Buffer} 49 | 50 | * **jconv.encodingExists( encodingName )** 51 | * `return` {Boolean} 52 | 53 | ## 速度 54 | node-iconv@2.0.7 との変換速度の比較です。[夏目漱石 こころ](http://www.aozora.gr.jp/cards/000148/files/773_14560.html) 55 | のテキストを、 [Benchmark.js](https://github.com/bestiejs/benchmark.js) を利用して変換速度を計測したものになります。 56 | 環境は *Windows7, core i5 2405-S, mem8G, Node 0.10.22*です。 (利用する環境で計測してみてください。) 57 | `グレー`がiconv、`青色`がjconvで、高い方がより高速です。 58 | 59 | ![jconv - encoding speed test chart](./test/chart/speedLog.png) 60 | [[latest log]](./test/chart/speedLog.txt) 61 | 62 | 63 | ## エンコードについて 64 | * Shift_JIS(CP932), ISO-2022-JP(-1), EUC-JP, UTF8, UNICODE(UCS2) の相互変換をサポートしています。 65 | 「秀丸エディタ」とほぼ同じ変換内容になります。 66 | 67 | * Windowsの機種依存文字を変換できます。 68 | [(問題詳細)](http://support.microsoft.com/default.aspx?scid=kb;ja;JP170559) 69 | 70 | * "JIS X 0208"、"JIS X 0212"、"CP932" には、ユニコード変換テーブルに相違点があり、 71 | いくつかの特殊な文字 ( ~¢£∥ など ) では、デフォルトで相互変換を行うことが出来ません。 72 | このモジュールではテーブルの修正を行うことで相互変換できるようにしていますが、 73 | 定義に厳格な変換を行いたい場合は、 node-iconv に libiconv の日本語用修正パッチを当てたモジュールを使用してください。 74 | [(問題詳細)](http://www8.plala.or.jp/tkubota1/unicode-symbols-map2.html) 75 | 76 | ## 参考 77 | * [iconv-lite](https://github.com/ashtuchkin/iconv-lite) by ashtuchkin. 78 | * [Encoding.js](https://github.com/polygonplanet/Unzipper.js) by polygonplanet. 79 | * [iconv-js](https://github.com/Hikaru02/iconv-js) by Hikaru02. 80 | * [node-iconv](https://github.com/bnoordhuis/node-iconv) by bnoordhuis. 81 | * [libiconv-1.9.1-ja-patch Description](http://www2d.biglobe.ne.jp/~msyk/software/libiconv-1.9.1-patch.html) by 森山 将之. 82 | 83 | ありがとうございます。 84 | 85 | ## Note 86 | Pull requests are welcome. 87 | 88 | ## Todo 89 | * Streaming API support 90 | -------------------------------------------------------------------------------- /Translation.md: -------------------------------------------------------------------------------- 1 | 2 | # How to translate Ys VIII with these tools ? 3 | 4 | - First you need the Japanese (PCSG00881) game with the 1.02 update & the dumped english assets including the 1.01 update (tested on the EUR version, PCSB01128). Seems the chinese game as base works better though ! 5 | - Replace rootast.xai & patch101.xai with english ones first 6 | - Now, we need to fix the japanese patch102.xai with english. 7 | To do that, use the XAST Unpacker to extract english rootast.xai & patch101.xai & japanese patch102.xai 8 | - Now replace all files in patch102.xai with their english version in patch101.xai, or rootast.xai if not in 1.01, except flash/pkg_menu.xai & system/1stload.dat which must not change 9 | - Then, we must patch the japanese system/1stload.dat 10 | - First use the DAT Unpacker to extract both japanese / english system/1stload.dat files 11 | - Now use the `swap.sh` bash script on `1stload.list` and english then japanese directories created in last step. 12 | Something like `./swap.sh 1stload.list 1stload_eng/ 1stload_jap/`, otherwise you can just replace each non-commented file in `1stload.list` with its english version (`swap.sh` does that) 13 | - Some files from 1stload.list will be missing from the extracted english 1stload.dat, so just check which ones are missing according to what failed on last step & get those files from the extracted patch101.xai or else rootast.xai english files. 14 | Then, reproduce the last step again, it should work fine now. 15 | - Now we'll patch the japanese flash/pkg_menu.xai 16 | - First use the XAST Unpacker to extract both japanese / english flash/pkg_menu.xai files 17 | - Now use the `swap.sh` bash script on `pkg_menu.list` and english then japanese directories created in last step. 18 | Something like `./swap.sh pkg_menu.list pkg_menu_eng/ pkg_menu_jap/`, otherwise you can just replace each non-commented file in `pkg_menu.list` with its english version (`swap.sh` does that) 19 | - For pl_const.plt & lit_rtxt.csv from from 1stload.dat, you need to hack more manually 20 | - For pl_const.plt, just use the english one for the chinese game. For the Japanese game, you have to convert the encoding to SHIFT-JIS by first unpacking it, & then once fixed repack it using the PLT tools 21 | - For lit_rtxt.csv, with the Japanese game you have to convert the encoding to SHIFT-JIS again. 22 | Then, you must change the quote system used here. Indeed, english uses quotes like "this", you have to convert them to something like 「this」 (take the quote characters directly from the original game's file to make sure the encoding is right !) 23 | - Now for the japanese version only, unpack & then repack uncommented files from tbb2shift.list in 1stload.dat using TBB tools with `--enc shift-jis`, & place these in your patched 1stload folder (this should fix encoding issues) 24 | - Finally, repack the fixed 1stload.dat & pkg_menu.xai files using the `dat` & `xai` tools, use it as system/1stload.dat & flash/pkg_menu.xai in 102 & then repack 102 using the XAST Packer. 25 | Something like `./xai patch102_fix patch102_fixed.xai patch102_untouched.xai` 26 | - Finished for patch 1.02, just use the generated patch102_fixed.xai file as patch102.xai in your japanese game folder & have fun. 27 | - Some other steps are required to fix some encoding issues in scenes for instance, for that you can use the `encScripts.sh` script. Some other smalls files need encoding fixes (details) &, also some files have $n separators which must be converted to spaces instead 28 | - Additionally, you can use the eboot patcher below to fix some details from the eboot itself 29 | -------------------------------------------------------------------------------- /undat.cpp: -------------------------------------------------------------------------------- 1 | // XAST Unpacker by yosh778 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | uint32_t read32(std::ifstream& input) { 13 | uint32_t data; 14 | input.read((char*)&data, (int)sizeof(data)); 15 | return data; 16 | } 17 | 18 | uint64_t read64(std::ifstream& input) { 19 | uint64_t data; 20 | input.read((char*)&data, (int)sizeof(data)); 21 | return data; 22 | } 23 | 24 | int main(int argc, char *argv[]) 25 | { 26 | if ( argc < 3 ) { 27 | std::cerr << "Usage : " << argv[0] << " " << std::endl; 28 | return -1; 29 | } 30 | 31 | std::string iDir = argv[1]; 32 | std::string oDir = argv[2]; 33 | 34 | std::ifstream file( iDir.c_str(), std::ios_base::binary ); 35 | 36 | if ( !file.is_open() ) 37 | return -2; 38 | 39 | uint32_t data; 40 | 41 | // Version : 1.01 42 | uint32_t nbEntries = read32(file); // nbEntries 43 | nbEntries = read32(file); // nbEntries 44 | nbEntries = read32(file); // nbEntries 45 | nbEntries = read32(file); // nbEntries 46 | uint32_t dataOffset = 0x10 + 0x20 * nbEntries; 47 | 48 | // std::cout << "Number of declared entries : " << nbEntries << std::endl; 49 | 50 | uint64_t *fileSizes = new uint64_t[nbEntries]; 51 | uint64_t *fileOffsets = new uint64_t[nbEntries]; 52 | uint32_t i = 0; 53 | 54 | char **fileNames = new char*[nbEntries]; 55 | 56 | for (i = 0; i < nbEntries; i++) { 57 | 58 | char *fileName = new char[0x10]; 59 | file.read(fileName, 0x10); 60 | fileNames[i] = fileName; 61 | std::cout << fileName << std::endl; 62 | 63 | // std::cout << "fileoffset : 0x" << std::hex << file.tellg() << std::endl; 64 | fileOffsets[i] = read32(file); 65 | fileSizes[i] = read32(file); 66 | // std::cout << "offset : 0x" << std::hex << fileOffsets[i] << std::endl; 67 | // std::cout << "size : 0x" << std::hex << fileSizes[i] << std::endl; 68 | 69 | uint32_t padding = read64(file); 70 | } 71 | 72 | if ( file.tellg() != dataOffset ) { 73 | std::cerr << "Error while reading header : " << std::hex << file.tellg() 74 | << " != " << dataOffset << std::dec << std::endl; 75 | return -2; 76 | } 77 | 78 | 79 | uint8_t *buf = NULL; 80 | uint32_t bufSize = 0; 81 | uint32_t nFoundEntries = 0; 82 | 83 | for ( i = 0; i < nbEntries; i++ ) { 84 | 85 | uint32_t offset = fileOffsets[i]; 86 | uint32_t size = fileSizes[i]; 87 | 88 | if ( !offset || !size ) 89 | continue; 90 | 91 | nFoundEntries++; 92 | // std::cout << "Number of extracted entries : " << std::dec << nFoundEntries << std::endl; 93 | // std::cout << "offset : 0x" << std::hex << offset << std::endl; 94 | // std::cout << "size : 0x" << std::dec << size << std::endl; 95 | 96 | file.seekg( offset ); 97 | 98 | if ( size > bufSize ) { 99 | buf = (uint8_t*)realloc( buf, size ); 100 | bufSize = size; 101 | } 102 | 103 | file.read( (char*)buf, size ); 104 | 105 | std::string base = fileNames[i]; 106 | std::string opath( oDir + "/" + base ); 107 | std::cout << base << std::endl; 108 | 109 | 110 | boost::system::error_code returnedError; 111 | boost::filesystem::path path( opath ); 112 | //std::cout << path.parent_path() << std::endl; 113 | 114 | boost::filesystem::create_directories( 115 | path.parent_path(), returnedError 116 | ); 117 | 118 | 119 | std::ofstream output( opath.c_str(), std::ios_base::trunc | std::ios_base::binary ); 120 | 121 | if ( !output.is_open() ) 122 | continue; 123 | 124 | output.write( (char*)buf, size ); 125 | output.close(); 126 | } 127 | 128 | std::cerr << 129 | std::endl << "Number of declared entries : " << nbEntries << std::endl; 130 | std::cerr << "Number of extracted entries : " << nFoundEntries << std::endl; 131 | 132 | file.close(); 133 | 134 | return 0; 135 | } 136 | 137 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ys VIII Unpacking / Packing tools 2 | 3 | Unpacking & Packing tools for Ys VIII assets 4 | 5 | 6 | ## How to translate Ys VIII with it ? 7 | 8 | Follow the guide [here](https://github.com/yosh778/YsVIII-tools/blob/master/Translation.md). 9 | 10 | WARNING : This guide is mostly informative may not contain some complex or more recent steps 11 | 12 | ## Eboot patcher 13 | 14 | Usage : `python3 patchEboot.py ` 15 | 16 | This python script enables you to apply eboot specific patches. For mai dumps, run it on both the base eboot.bin & mai_moe/eboot_origin.bin. 17 | This patch allows you to get the savedata level text to display as "Lv 17" instead of "Lv17" for instance, just like the US/EU game does. 18 | 19 | 20 | ## XAST 21 | ### Unpacker 22 | 23 | Usage : `unxai ` 24 | 25 | Extracts all files from an input XAST archive into the given output directory. 26 | 27 | 28 | ### Packer 29 | 30 | Usage : `xai ()` 31 | 32 | Packs a whole folder as a XAST output archive. 33 | 34 | If the original .xai archive is given as third argument, 35 | it will use the same header structure to avoid game compatibility issues (recommanded). 36 | 37 | WARNING : When specifying the original .xai, DO NOT add new files (not supported yet). 38 | 39 | 40 | ### Patcher 41 | 42 | Usage : `xaiPatch ` 43 | 44 | Replaces a specific file from the input XAST archive with a new one. 45 | You must provide the correct filepath from the XAST archive as filename (example : flash/pl_const.plt) 46 | 47 | WARNING : both files must be the same size 48 | 49 | 50 | ## DAT 51 | ### Unpacker 52 | 53 | Usage : `undat ` 54 | 55 | Extracts all files from an input DAT archive into the given output directory. 56 | 57 | 58 | ### Packer 59 | 60 | Usage : `dat ` 61 | 62 | Packs a whole folder as a DAT output archive. 63 | 64 | WARNING : filenames must not be more than 15 characters, also no folder structure should be used in theory. 65 | 66 | ## PLT 67 | ### Unpacker 68 | 69 | Usage : `unplt ` 70 | 71 | Extracts all strings from an input PLT archive into the given output text file. 72 | 73 | ### Packer 74 | 75 | Usage : `plt ` 76 | 77 | Packs all strings from an input text file into the given output PLT archive. 78 | 79 | ## TBB 80 | 81 | Requires Node.js 6+ (8.5 recommended) 82 | 83 | ### Unpacker 84 | 85 | Usage : `node tbbconv/tbbconv.js unpack ` 86 | 87 | Converts a TBB input file into a CSV output file. 88 | 89 | 90 | ### Packer 91 | 92 | Usage : `node tbbconv/tbbconv.js pack (--enc shift-jis)` 93 | 94 | Converts a CSV input file into a TBB output file. 95 | 96 | When workingon the Japanese game, add the `--enc shift-jis` argument to repack into shift-jis. 97 | 98 | 99 | ## Scripting 100 | 101 | ### Disassembler 102 | 103 | Usage : `bin2script ` 104 | 105 | Converts a bytecode script into text. 106 | Credits to [weaknespase](https://github.com/weaknespase) for the [file format reverse](https://gist.github.com/weaknespase/d0a26fbc21a77616199969fe08cd48c2) 107 | 108 | 109 | ### Assembler 110 | 111 | Usage : `script2bin