├── MANIFEST.in ├── testing ├── data │ ├── clsca.zip │ ├── emma.zip │ ├── genpe.zip │ ├── linda.zip │ ├── mikdp.zip │ ├── butou5.zip │ ├── gimcho.zip │ ├── hol6po.zip │ ├── ia6cho.zip │ ├── imcanz.zip │ ├── senpac.zip │ ├── shoto9.zip │ ├── dummy_tjas │ │ ├── notes_hands.tja │ │ ├── notes_double_kusudama.tja │ │ ├── basic_song.tja │ │ ├── missing_course.tja │ │ ├── missing_level.tja │ │ ├── missing_balloon.tja │ │ ├── notes_sim_only.tja │ │ ├── missing_score.tja │ │ ├── notes_senotechange.tja │ │ ├── basic_song_2P.tja │ │ └── unsupported.tja │ ├── clsca.tja │ ├── mikdp.tja │ ├── butou5.tja │ ├── shoto9.tja │ ├── senpac.tja │ ├── gimcho.tja │ ├── ia6cho.tja │ ├── linda.tja │ ├── hol6po.tja │ └── imcanz.tja ├── test_command_support.py ├── conftest.py ├── test_custom_tjas.py └── test_conversion.py ├── setup.py ├── .github └── workflows │ ├── check_code_quality.yml │ └── test_and_publish_release.yml ├── LICENSE.txt ├── pyproject.toml ├── src └── tja2fumen │ ├── writers.py │ ├── constants.py │ ├── __init__.py │ └── classes.py ├── .gitignore └── README.md /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include src/tja2fumen/hp_values.csv 2 | -------------------------------------------------------------------------------- /testing/data/clsca.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivaria/tja2fumen/HEAD/testing/data/clsca.zip -------------------------------------------------------------------------------- /testing/data/emma.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivaria/tja2fumen/HEAD/testing/data/emma.zip -------------------------------------------------------------------------------- /testing/data/genpe.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivaria/tja2fumen/HEAD/testing/data/genpe.zip -------------------------------------------------------------------------------- /testing/data/linda.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivaria/tja2fumen/HEAD/testing/data/linda.zip -------------------------------------------------------------------------------- /testing/data/mikdp.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivaria/tja2fumen/HEAD/testing/data/mikdp.zip -------------------------------------------------------------------------------- /testing/data/butou5.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivaria/tja2fumen/HEAD/testing/data/butou5.zip -------------------------------------------------------------------------------- /testing/data/gimcho.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivaria/tja2fumen/HEAD/testing/data/gimcho.zip -------------------------------------------------------------------------------- /testing/data/hol6po.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivaria/tja2fumen/HEAD/testing/data/hol6po.zip -------------------------------------------------------------------------------- /testing/data/ia6cho.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivaria/tja2fumen/HEAD/testing/data/ia6cho.zip -------------------------------------------------------------------------------- /testing/data/imcanz.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivaria/tja2fumen/HEAD/testing/data/imcanz.zip -------------------------------------------------------------------------------- /testing/data/senpac.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivaria/tja2fumen/HEAD/testing/data/senpac.zip -------------------------------------------------------------------------------- /testing/data/shoto9.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vivaria/tja2fumen/HEAD/testing/data/shoto9.zip -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from setuptools import setup 4 | 5 | if __name__ == "__main__": 6 | setup() 7 | -------------------------------------------------------------------------------- /testing/data/dummy_tjas/notes_hands.tja: -------------------------------------------------------------------------------- 1 | // This song contains only basic notes. 2 | BPM:120 3 | OFFSET:-1.00 4 | 5 | COURSE:Oni 6 | LEVEL:10 7 | BALLOON:8,8 8 | SCOREINIT:400 9 | SCOREDIFF:100 10 | 11 | #START 12 | A0B0, 13 | #END 14 | -------------------------------------------------------------------------------- /testing/data/dummy_tjas/notes_double_kusudama.tja: -------------------------------------------------------------------------------- 1 | // This song contains only basic notes. 2 | BPM:120 3 | OFFSET:-1.00 4 | 5 | COURSE:Oni 6 | LEVEL:10 7 | BALLOON:8,8 8 | SCOREINIT:400 9 | SCOREDIFF:100 10 | 11 | #START 12 | 9000, 13 | 9008, 14 | #END 15 | -------------------------------------------------------------------------------- /testing/data/dummy_tjas/basic_song.tja: -------------------------------------------------------------------------------- 1 | // This song contains only basic notes. 2 | BPM:120 3 | OFFSET:-1.00 4 | 5 | COURSE:Oni 6 | LEVEL:10 7 | BALLOON:8,8 8 | SCOREINIT:400 9 | SCOREDIFF:100 10 | 11 | #START 12 | 1020304, 13 | 5000008, 14 | 6000008, 15 | 7000008, 16 | 9000008, 17 | #END 18 | -------------------------------------------------------------------------------- /testing/data/dummy_tjas/missing_course.tja: -------------------------------------------------------------------------------- 1 | // This song contains only basic notes. 2 | BPM:120 3 | OFFSET:-1.00 4 | 5 | COURSE: 6 | LEVEL:10 7 | BALLOON:8,8 8 | SCOREINIT:400 9 | SCOREDIFF:100 10 | 11 | #START 12 | 1020304, 13 | 5000008, 14 | 6000008, 15 | 7000008, 16 | 9000008, 17 | #END 18 | -------------------------------------------------------------------------------- /testing/data/dummy_tjas/missing_level.tja: -------------------------------------------------------------------------------- 1 | // This song contains only basic notes. 2 | BPM:120 3 | OFFSET:-1.00 4 | 5 | COURSE:Oni 6 | LEVEL: 7 | BALLOON:8,8 8 | SCOREINIT:400 9 | SCOREDIFF:100 10 | 11 | #START 12 | 1020304, 13 | 5000008, 14 | 6000008, 15 | 7000008, 16 | 9000008, 17 | #END 18 | -------------------------------------------------------------------------------- /testing/data/dummy_tjas/missing_balloon.tja: -------------------------------------------------------------------------------- 1 | // This song is missing the `BALLOON:` metadata 2 | BPM:120 3 | OFFSET:-1.00 4 | 5 | COURSE:Oni 6 | LEVEL:10 7 | BALLOON: 8 | SCOREINIT:400 9 | SCOREDIFF:100 10 | 11 | #START 12 | 1020304, 13 | 5000008, 14 | 6000008, 15 | 7000008, 16 | 9000008, 17 | #END 18 | -------------------------------------------------------------------------------- /testing/data/dummy_tjas/notes_sim_only.tja: -------------------------------------------------------------------------------- 1 | // This song contains only basic notes. 2 | BPM:120 3 | OFFSET:-1.00 4 | 5 | COURSE:Oni 6 | LEVEL:10 7 | BALLOON:8,8 8 | SCOREINIT:400 9 | SCOREDIFF:100 10 | 11 | #START 12 | C0C0, 13 | D008, 14 | E0E0, 15 | F0F0, 16 | G0G0, 17 | H008, 18 | I008, 19 | #END 20 | -------------------------------------------------------------------------------- /testing/data/dummy_tjas/missing_score.tja: -------------------------------------------------------------------------------- 1 | // This song is missing `SCOREINIT:` and `SCOREDIFF:` metadata 2 | BPM:120 3 | OFFSET:-1.00 4 | 5 | COURSE:Oni 6 | LEVEL:10 7 | BALLOON:8,8 8 | SCOREINIT: 9 | SCOREDIFF: 10 | 11 | #START 12 | 1020304, 13 | 5000008, 14 | 6000008, 15 | 7000008, 16 | 9000008, 17 | #END 18 | -------------------------------------------------------------------------------- /testing/data/dummy_tjas/notes_senotechange.tja: -------------------------------------------------------------------------------- 1 | // This song contains only basic notes. 2 | BPM:120 3 | OFFSET:-1.00 4 | 5 | COURSE:Oni 6 | LEVEL:10 7 | BALLOON:8,8 8 | SCOREINIT:400 9 | SCOREDIFF:100 10 | 11 | #START 12 | #SENOTECHANGE 3 13 | 1 14 | #SENOTECHANGE 2 15 | 111111, 16 | 1020304, 17 | 5000008, 18 | 6000008, 19 | 7000008, 20 | 9000008, 21 | #END 22 | -------------------------------------------------------------------------------- /testing/data/dummy_tjas/basic_song_2P.tja: -------------------------------------------------------------------------------- 1 | // This song contains only basic notes. 2 | BPM:120 3 | OFFSET:-1.00 4 | 5 | COURSE:Oni 6 | LEVEL:10 7 | BALLOON:8,8 8 | SCOREINIT:400 9 | SCOREDIFF:100 10 | STYLE:Single 11 | 12 | #START 13 | 1020304, 14 | 5000008, 15 | 6000008, 16 | 7000008, 17 | 9000008, 18 | #END 19 | 20 | BALLOON:8,8 21 | SCOREINIT:400 22 | SCOREDIFF:100 23 | STYLE:Double 24 | 25 | #START P1 26 | 1020304, 27 | 5000008, 28 | 6000008, 29 | 7000008, 30 | 9000008, 31 | #END 32 | 33 | #START P2 34 | 1020304, 35 | 5000008, 36 | 6000008, 37 | 7000008, 38 | 9000008, 39 | #END -------------------------------------------------------------------------------- /.github/workflows/check_code_quality.yml: -------------------------------------------------------------------------------- 1 | #file: noinspection LongLine 2 | name: "Check code quality" 3 | 4 | on: 5 | push: 6 | branches: 7 | - main 8 | pull_request: 9 | branches: 10 | - '*' 11 | 12 | jobs: 13 | check-code-quality: 14 | runs-on: windows-2019 15 | steps: 16 | - name: Checkout tja2fumen 17 | uses: actions/checkout@v3 18 | 19 | - name: Set up Python 20 | uses: actions/setup-python@v4 21 | with: 22 | python-version: '3.8.x' 23 | 24 | - name: Install tja2fumen and its dev dependencies 25 | run: | 26 | pip install -e .[dev] 27 | 28 | - name: Simple linting using flake8 29 | run: pflake8 30 | 31 | - name: Strict linting using pylint 32 | run: pylint src 33 | 34 | - name: Type analysis using mypy 35 | run: mypy src --strict 36 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Vivaria 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /testing/data/dummy_tjas/unsupported.tja: -------------------------------------------------------------------------------- 1 | // This song contains all unsupported metadata/commands. 2 | TITLE:Test 3 | TITLEJA:テスト 4 | TITLEEN:Test 5 | SUBTITLE:Test 6 | SUBTITLEJA:テスト 7 | SUBTITLEEN:Test 8 | BPM:120 9 | OFFSET:-1.00 10 | DEMOSTART:1.00 11 | GENRE:J-POP 12 | SCOREMODE:1 13 | WAVE:Test.ogg 14 | MAKER:Test 15 | LYRICS:Test.vtt 16 | SONGVOL:100 17 | SEVOL:100 18 | SIDE:1 19 | LIFE:0 20 | GAME:Taiko 21 | HEADSCROLL:1 22 | BGIMAGE:Test.png 23 | BGMOVIE:Test.avi 24 | MOVIEOFFSET:1.00 25 | PREIMAGE:Test.png 26 | TAIKOWEBSKIN:dir ../song_skins,name miku,song static,stage none,don fastscroll 27 | 28 | COURSE:Oni 29 | LEVEL:10 30 | BALLOON:8,8 31 | SCOREINIT:400 32 | SCOREDIFF:100 33 | BALLOONNOR:8,8 34 | BALLOONEXP:10,10 35 | BALLOONMAS:12,12 36 | EXAM1:g,98,100,m 37 | EXAM2:jp,1000,1150,m 38 | EXAM3:jb,10,5,l 39 | GAUGEINCR:Normal 40 | TOTAL:200 41 | HIDDENBRANCH:1 42 | NOTESDESIGNER4:Test 43 | NOTESDESIGNER3:Test 44 | NOTESDESIGNER2:Test 45 | NOTESDESIGNER1:Test 46 | NOTESDESIGNER0:Test 47 | 48 | #BMSCROLL 49 | #HBSCROLL 50 | #START 51 | #SENOTECHANGE 3 52 | 1020304, 53 | #LYRIC Test lyric 54 | 5000008, 55 | #DIRECTION 2 56 | 6000008, 57 | #SUDDEN 2 1 58 | 7000008, 59 | #JPOSSCROLL 2 760 1 60 | 9000008, 61 | #END 62 | 63 | #NEXTSONG GO!GO!明るい社会,うるまでるび,バラエティ,GO!GO!明るい社会.ogg,560,160 64 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "tja2fumen" 3 | version = "0.0.dev0" 4 | description = "Convert TJA chart files into fumen (.bin) chart files" 5 | readme = "README.md" 6 | requires-python = ">=3.8" 7 | license = {file = "LICENSE.txt"} 8 | keywords = ["taiko", "tatsujin", "fumen", "TJA"] 9 | 10 | [project.urls] # Optional 11 | "Homepage" = "https://github.com/vivaria/tja2fumen/" 12 | "Bug Reports" = "https://github.com/vivaria/tja2fumen/issues/" 13 | "Source" = "https://github.com/vivaria/tja2fumen/" 14 | 15 | # The following would provide a command line executable called `sample` 16 | # which executes the function `main` from this package when invoked. 17 | [project.scripts] # Optional 18 | tja2fumen = "tja2fumen:main" 19 | 20 | [project.optional-dependencies] 21 | dev = ["pytest", "build", "pyinstaller", "twine", "toml-cli", 22 | "flake8", "pyproject-flake8", "mypy", "pylint"] 23 | 24 | [tool.setuptools.packages.find] 25 | where = ["src"] 26 | 27 | [tool.pytest.ini_options] 28 | addopts = "-vv --tb=short --color=yes" 29 | console_output_style = "count" 30 | disable_test_id_escaping_and_forfeit_all_rights_to_community_support = "True" 31 | 32 | [tool.flake8] 33 | exclude = "venv/" 34 | per-file-ignores = """ 35 | ./src/tja2fumen/classes.py: E221 36 | ./testing/test_conversion.py: E221, E272 37 | """ 38 | 39 | [tool.pylint.'MESSAGES CONTROL'] 40 | disable = """ 41 | too-many-instance-attributes, 42 | too-many-branches, 43 | too-many-arguments, 44 | too-many-locals, 45 | too-many-statements, 46 | too-many-positional-arguments, 47 | fixme 48 | """ 49 | -------------------------------------------------------------------------------- /testing/test_command_support.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | 4 | import pytest 5 | 6 | from conftest import convert 7 | 8 | 9 | @pytest.mark.parametrize('id_song,err_msg', [ 10 | ['basic_song', None], 11 | ['basic_song_2P', None], 12 | ['unsupported', 'UserWarning'], 13 | ['notes_double_kusudama', None], 14 | ['notes_hands', None], 15 | ['notes_sim_only', None], 16 | ['notes_senotechange', None], 17 | ['missing_score', None], 18 | ['missing_balloon', "UserWarning"], 19 | ['missing_course', "Invalid COURSE value:"], 20 | ['missing_level', "Invalid LEVEL value:"] 21 | ]) 22 | @pytest.mark.skipif("CI" in os.environ, reason="Local-only") 23 | def test_expected_errors(id_song, err_msg, tmp_path, entry_point): 24 | # Define the testing directory 25 | path_test = os.path.dirname(os.path.realpath(__file__)) 26 | 27 | # Define the working directory 28 | path_temp = os.path.join(tmp_path, id_song) 29 | os.mkdir(path_temp) 30 | 31 | # Copy input TJA to working directory 32 | path_tja = os.path.join(path_test, "data", "dummy_tjas", f"{id_song}.tja") 33 | path_tja_tmp = os.path.join(path_temp, f"{id_song}.tja") 34 | shutil.copy(path_tja, path_tja_tmp) 35 | 36 | # Try to convert TJA file to fumen files, then check the error traceback 37 | if err_msg and 'Warning' in err_msg: 38 | with pytest.warns(): 39 | convert(path_test, path_tja_tmp, entry_point) 40 | else: 41 | tb = convert(path_test, path_tja_tmp, entry_point, err_msg) 42 | if err_msg: 43 | assert err_msg in tb 44 | else: 45 | assert tb == '' 46 | -------------------------------------------------------------------------------- /testing/conftest.py: -------------------------------------------------------------------------------- 1 | import glob 2 | import os 3 | import subprocess 4 | from subprocess import CalledProcessError 5 | 6 | import pytest 7 | 8 | from tja2fumen import main as api_convert 9 | 10 | 11 | def pytest_addoption(parser): 12 | parser.addoption("--entry-point", action="store", default="python-api") 13 | 14 | 15 | @pytest.fixture 16 | def entry_point(request): 17 | return request.config.getoption("--entry-point") 18 | 19 | 20 | def convert(path_test, path_tja_tmp, entry_point, err_msg=None): 21 | tb = '' 22 | 23 | if entry_point == "python-api": 24 | if not err_msg: 25 | api_convert(argv=[path_tja_tmp]) 26 | else: 27 | try: 28 | api_convert(argv=[path_tja_tmp]) 29 | except Exception as e: 30 | tb = str(e) 31 | 32 | elif entry_point == "python-cli": 33 | if not err_msg: 34 | subprocess.check_output(f"tja2fumen {path_tja_tmp}", text=True, 35 | shell=True, stderr=subprocess.STDOUT) 36 | else: 37 | try: 38 | subprocess.check_output(f"tja2fumen {path_tja_tmp}", text=True, 39 | shell=True, stderr=subprocess.STDOUT) 40 | except CalledProcessError as e: 41 | tb = str(e) 42 | 43 | elif entry_point == "exe": 44 | exe_glob = os.path.join(os.path.split(path_test)[0], "dist", "*.exe") 45 | exe = glob.glob(exe_glob)[0] 46 | if not err_msg: 47 | subprocess.check_output(f"{exe} {path_tja_tmp}", text=True, 48 | shell=True, stderr=subprocess.STDOUT) 49 | else: 50 | try: 51 | subprocess.check_output(f"{exe} {path_tja_tmp}", text=True, 52 | shell=True, stderr=subprocess.STDOUT) 53 | except CalledProcessError as e: 54 | tb = str(e) 55 | 56 | return tb 57 | -------------------------------------------------------------------------------- /testing/test_custom_tjas.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | import glob 4 | 5 | import pytest 6 | 7 | from conftest import convert 8 | from tja2fumen.parsers import parse_fumen 9 | 10 | CUSTOM_TJA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), 11 | "data", "custom_tjas") 12 | # CUSTOM_TJA_DIR = os.path.join("D:\\", "games", "TaikoTDM", 13 | # "CustomSongSources", "ESE") 14 | CUSTOM_TJAS = sum([ 15 | # For each file in the subfolder, keep only if it ends in `.tja` 16 | [(root, f) for f in files if f.endswith(".tja")] 17 | # Iterate through all subfolders in the "unpaired_tjas" folder 18 | for root, _, files in os.walk(CUSTOM_TJA_DIR) 19 | ], []) # sum([list of lists], []) -> https://stackoverflow.com/a/716489 20 | CUSTOM_TJA_PATHS = [os.path.join(root, f) for (root, f) in CUSTOM_TJAS] 21 | CUSTOM_TJA_IDS = [f for (root, f) in CUSTOM_TJAS] 22 | 23 | 24 | @pytest.mark.parametrize('path_tja', CUSTOM_TJA_PATHS, ids=CUSTOM_TJA_IDS) 25 | @pytest.mark.skipif("CI" in os.environ, 26 | reason="Test is only for local debugging") 27 | def test_converted_custom_tjas(path_tja, tmp_path, entry_point): 28 | """ 29 | A test purely to aid with debugging. It lets me drop a .tja into a 30 | pre-determined folder and run the conversion, allowing me to set 31 | breakpoints and debug internal state without any tedious setup. 32 | """ 33 | # Define the testing directory 34 | path_test = os.path.dirname(os.path.realpath(__file__)) 35 | 36 | # Copy input TJA to working directory 37 | path_tja_tmp = str(tmp_path / "test.tja") 38 | shutil.copy(path_tja, path_tja_tmp) 39 | 40 | # Convert TJA file to fumen files 41 | convert(path_test, path_tja_tmp, entry_point) 42 | 43 | # Fetch output fumen paths 44 | paths_out = glob.glob(os.path.join(tmp_path, "*.bin")) 45 | assert paths_out, f"No bin files generated in {tmp_path}" 46 | order = "xmhne" # Ura Oni -> Oni -> Hard -> Normal -> Easy 47 | paths_out = sorted(paths_out, 48 | key=lambda s: [order.index(c) if c in order 49 | else len(order) for c in s]) 50 | for path_out in paths_out: 51 | parse_fumen(path_out, exclude_empty_measures=False) 52 | -------------------------------------------------------------------------------- /src/tja2fumen/writers.py: -------------------------------------------------------------------------------- 1 | """ 2 | Functions for writing song data to fumen files (.bin) 3 | """ 4 | 5 | import struct 6 | from typing import BinaryIO, Any, List 7 | 8 | from tja2fumen.classes import FumenCourse 9 | from tja2fumen.constants import BRANCH_NAMES, FUMEN_TYPE_NOTES 10 | 11 | 12 | def write_fumen(path_out: str, song: FumenCourse) -> None: 13 | """ 14 | Write the values in a FumenCourse object to a `.bin` file. 15 | 16 | This operation is the reverse of the `parse_fumen` function. Please refer 17 | to that function for more details about the fumen file structure. 18 | """ 19 | with open(path_out, "wb") as file: 20 | file.write(song.header.raw_bytes) 21 | 22 | for measure in song.measures: 23 | measure_struct = ([measure.bpm, measure.offset_start, 24 | int(measure.gogo), int(measure.barline), 25 | measure.padding1] + measure.branch_info + 26 | [measure.padding2]) 27 | write_struct(file, song.header.order, 28 | format_string="ffBBHiiiiiii", 29 | value_list=measure_struct) 30 | 31 | for branch_name in BRANCH_NAMES: 32 | branch = measure.branches[branch_name] 33 | branch_struct = [branch.length, branch.padding, branch.speed] 34 | write_struct(file, song.header.order, 35 | format_string="HHf", 36 | value_list=branch_struct) 37 | 38 | for note in branch.notes: 39 | note_struct = [FUMEN_TYPE_NOTES[note.note_type], note.pos, 40 | note.item, note.padding] 41 | if note.hits: 42 | extra_vals = [note.hits, note.hits_padding] 43 | else: 44 | # Max value for H -> 0xffff -> 65535 45 | extra_vals = [min(65535, note.score_init), 46 | min(65535, note.score_diff * 4)] 47 | note_struct.extend(extra_vals) 48 | note_struct.append(note.duration) 49 | write_struct(file, song.header.order, 50 | format_string="ififHHf", 51 | value_list=note_struct) 52 | 53 | if note.note_type.lower() == "drumroll": 54 | file.write(note.drumroll_bytes) 55 | 56 | 57 | def write_struct(file: BinaryIO, 58 | order: str, 59 | format_string: str, 60 | value_list: List[Any]) -> None: 61 | """Pack (int, float, etc.) values into a string of bytes, then write.""" 62 | try: 63 | packed_bytes = struct.pack(order + format_string, *value_list) 64 | except struct.error as err: 65 | raise ValueError(f"Can't fmt {value_list} as {format_string}") from err 66 | file.write(packed_bytes) 67 | -------------------------------------------------------------------------------- /src/tja2fumen/constants.py: -------------------------------------------------------------------------------- 1 | """ 2 | Constant song properties of TJA and fumen files. 3 | """ 4 | 5 | # Names for branches in diverge songs 6 | BRANCH_NAMES = ("normal", "professional", "master") 7 | 8 | # Types of notes that can be found in TJA files 9 | TJA_NOTE_TYPES = { 10 | '0': 'Blank', 11 | '1': 'Don', 12 | '2': 'Ka', 13 | '3': 'DON', 14 | '4': 'KA', 15 | '5': 'Drumroll', 16 | '6': 'DRUMROLL', 17 | '7': 'Balloon', 18 | '8': 'EndDRB', 19 | '9': 'Kusudama', 20 | 'A': 'DON2', # hands 21 | 'B': 'KA2', # hands 22 | 'C': 'Blank', # bombs 23 | 'D': 'Drumroll', # fuse roll 24 | 'E': 'DON2', # red + green single hit 25 | 'F': 'Ka', # ADLib (hidden note) 26 | 'G': 'KA2', # red + green double hit 27 | 'H': 'DRUMROLL', # double roll 28 | 'I': 'Drumroll', # green roll 29 | } 30 | 31 | # Conversion for TJAPlayer3's #SENOTECHANGE command 32 | SENOTECHANGE_TYPES = { 33 | 1: "Don", # ドン 34 | 2: "Don2", # ド 35 | 3: "Don3", # コ 36 | 4: "Ka", # カッ 37 | 5: "Ka2", # カ 38 | } 39 | 40 | # Types of notes that can be found in fumen files 41 | FUMEN_NOTE_TYPES = { 42 | 0x1: "Don", # ドン 43 | 0x2: "Don2", # ド 44 | 0x3: "Don3", # コ 45 | 0x4: "Ka", # カッ 46 | 0x5: "Ka2", # カ 47 | 0x6: "Drumroll", 48 | 0x7: "DON", 49 | 0x8: "KA", 50 | 0x9: "DRUMROLL", 51 | 0xa: "Balloon", 52 | 0xb: "DON2", # hands 53 | 0xc: "Kusudama", 54 | 0xd: "KA2", # hands 55 | 0xe: "Unknown1", # ? (Present in some Wii1 songs) 56 | 0xf: "Unknown2", # ? (Present in some PS4 songs) 57 | 0x10: "Unknown3", # ? (Present in some Wii1 songs) 58 | 0x11: "Unknown4", # ? (Present in some Wii1 songs) 59 | 0x12: "Unknown5", # ? (Present in some Wii4 songs) 60 | 0x13: "Unknown6", # ? (Present in some Wii1 songs) 61 | 0x14: "Unknown7", # ? (Present in some PS4 songs) 62 | 0x15: "Unknown8", # ? (Present in some Wii1 songs) 63 | 0x16: "Unknown9", # ? (Present in some Wii1 songs) 64 | 0x17: "Unknown10", # ? (Present in some Wii4 songs) 65 | 0x18: "Unknown11", # ? (Present in some PS4 songs) 66 | 0x19: "Unknown12", # ? (Present in some PS4 songs) 67 | 0x22: "Unknown13", # ? (Present in some Wii1 songs) 68 | 0x62: "Drumroll2" # ? 69 | } 70 | 71 | # Invert the dict to go from note type to fumen byte values 72 | FUMEN_TYPE_NOTES = {v: k for k, v in FUMEN_NOTE_TYPES.items()} 73 | 74 | # Normalize the various fumen course names into 1 name per difficulty 75 | NORMALIZE_COURSE = { 76 | '0': 'Easy', 77 | 'Easy': 'Easy', 78 | '1': 'Normal', 79 | 'Normal': 'Normal', 80 | '2': 'Hard', 81 | 'Hard': 'Hard', 82 | '3': 'Oni', 83 | 'Oni': 'Oni', 84 | '4': 'Ura', 85 | 'Ura': 'Ura', 86 | 'Edit': 'Ura' 87 | } 88 | 89 | # Fetch the 5 valid course names from NORMALIZE_COURSE's values 90 | COURSE_NAMES = list(set(NORMALIZE_COURSE.values())) 91 | 92 | # All combinations of difficulty and single/multiplayer type 93 | TJA_COURSE_NAMES = [] 94 | for difficulty in COURSE_NAMES: 95 | for player in ['', 'P1', 'P2']: 96 | TJA_COURSE_NAMES.append(difficulty+player) 97 | 98 | # Map course difficulty to filename IDs (e.g. Oni -> `song_m.bin`) 99 | COURSE_IDS = { 100 | 'Easy': 'e', 101 | 'Normal': 'n', 102 | 'Hard': 'h', 103 | 'Oni': 'm', 104 | 'Ura': 'x', 105 | } 106 | 107 | TIMING_WINDOWS = { 108 | # "GOOD" timing "OK" timing "BAD" timing 109 | 'Easy': (041.7083358764648, 108.441665649414, 125.125000000000), 110 | 'Normal': (041.7083358764648, 108.441665649414, 125.125000000000), 111 | 'Hard': (025.0250015258789, 075.075004577637, 108.441665649414), 112 | 'Oni': (025.0250015258789, 075.075004577637, 108.441665649414) 113 | } 114 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Custom song directory 2 | testing/data/custom_tjas/* 3 | 4 | # Byte-compiled / optimized / DLL files 5 | __pycache__/ 6 | *.py[cod] 7 | *$py.class 8 | 9 | # C extensions 10 | *.so 11 | 12 | # Distribution / packaging 13 | .Python 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | wheels/ 26 | share/python-wheels/ 27 | *.egg-info/ 28 | .installed.cfg 29 | *.egg 30 | MANIFEST 31 | 32 | # PyInstaller 33 | # Usually these files are written by a python script from a template 34 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 35 | *.manifest 36 | *.spec 37 | 38 | # Installer logs 39 | pip-log.txt 40 | pip-delete-this-directory.txt 41 | 42 | # Unit test / coverage reports 43 | htmlcov/ 44 | .tox/ 45 | .nox/ 46 | .coverage 47 | .coverage.* 48 | .cache 49 | nosetests.xml 50 | coverage.xml 51 | *.cover 52 | *.py,cover 53 | .hypothesis/ 54 | .pytest_cache/ 55 | cover/ 56 | 57 | # Translations 58 | *.mo 59 | *.pot 60 | 61 | # Django stuff: 62 | *.log 63 | local_settings.py 64 | db.sqlite3 65 | db.sqlite3-journal 66 | 67 | # Flask stuff: 68 | instance/ 69 | .webassets-cache 70 | 71 | # Scrapy stuff: 72 | .scrapy 73 | 74 | # Sphinx documentation 75 | docs/_build/ 76 | 77 | # PyBuilder 78 | .pybuilder/ 79 | target/ 80 | 81 | # Jupyter Notebook 82 | .ipynb_checkpoints 83 | 84 | # IPython 85 | profile_default/ 86 | ipython_config.py 87 | 88 | # pyenv 89 | # For a library or package, you might want to ignore these files since the code is 90 | # intended to run in multiple environments; otherwise, check them in: 91 | # .python-version 92 | 93 | # pipenv 94 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 95 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 96 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 97 | # install all needed dependencies. 98 | #Pipfile.lock 99 | 100 | # poetry 101 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 102 | # This is especially recommended for binary packages to ensure reproducibility, and is more 103 | # commonly ignored for libraries. 104 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 105 | #poetry.lock 106 | 107 | # pdm 108 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 109 | #pdm.lock 110 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 111 | # in version control. 112 | # https://pdm.fming.dev/#use-with-ide 113 | .pdm.toml 114 | 115 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 116 | __pypackages__/ 117 | 118 | # Celery stuff 119 | celerybeat-schedule 120 | celerybeat.pid 121 | 122 | # SageMath parsed files 123 | *.sage.py 124 | 125 | # Environments 126 | .env 127 | .venv 128 | env/ 129 | venv/ 130 | ENV/ 131 | env.bak/ 132 | venv.bak/ 133 | 134 | # Spyder project settings 135 | .spyderproject 136 | .spyproject 137 | 138 | # Rope project settings 139 | .ropeproject 140 | 141 | # mkdocs documentation 142 | /site 143 | 144 | # mypy 145 | .mypy_cache/ 146 | .dmypy.json 147 | dmypy.json 148 | 149 | # Pyre type checker 150 | .pyre/ 151 | 152 | # pytype static type analyzer 153 | .pytype/ 154 | 155 | # Cython debug symbols 156 | cython_debug/ 157 | 158 | # PyCharm 159 | # JetBrains specific template is maintained in a separate JetBrains.gitignore 160 | # that can be found at 161 | # https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore and 162 | # can be added to the global gitignore or merged into this file. For a more 163 | # nuclear option (not recommended) you can uncomment the following to ignore 164 | # the entire idea folder. 165 | .idea/ 166 | -------------------------------------------------------------------------------- /src/tja2fumen/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Entry points for tja2fumen. 3 | """ 4 | 5 | import argparse 6 | import os 7 | import shutil 8 | import sys 9 | from typing import Sequence, Tuple, List 10 | 11 | from tja2fumen.parsers import parse_tja, parse_fumen 12 | from tja2fumen.converters import convert_tja_to_fumen, fix_dk_note_types_course 13 | from tja2fumen.writers import write_fumen 14 | from tja2fumen.constants import COURSE_IDS 15 | from tja2fumen.classes import TJACourse 16 | 17 | 18 | def main(argv: Sequence[str] = ()) -> None: 19 | """ 20 | Main entry point for tja2fumen's command line interface. 21 | """ 22 | if not argv: 23 | argv = sys.argv[1:] 24 | 25 | parser = argparse.ArgumentParser( 26 | formatter_class=argparse.RawDescriptionHelpFormatter, 27 | description=""" 28 | tja2fumen is a tool to 29 | 30 | tja2fumen can be used in 3 ways: 31 | - If a .tja file is provided, then three steps are performed: 32 | 1. Parse TJA into multiple TJACourse objects. Then, for each course: 33 | 2. Convert TJACourse objects into FumenCourse objects. 34 | 3. Write each FumenCourse to its own .bin file. 35 | 36 | - If a .bin file is provided, then the existing .bin is repaired: 37 | 1. Update don/kat senote types to do-ko-don and ka-kat. 38 | 2. Update timing windows to fix previous bug with Easy/Normal timing. 39 | 40 | - If a folder is provided, then all .tja and .bin files will be recursively 41 | processed according to the above logic. (Confirmation is required for safety.) 42 | """ 43 | ) 44 | parser.add_argument( 45 | "input", 46 | help="Path to a Taiko no Tatsujin chart file or folder.", 47 | ) 48 | args = parser.parse_args(argv) 49 | path_input = getattr(args, "input") 50 | if os.path.isdir(path_input): 51 | print(f"Folder passed to tja2fumen. " 52 | f"Looking for files in {path_input}...\n") 53 | tja_files, bin_files = parse_files(path_input) 54 | print("\nThe following TJA files will be CONVERTED:") 55 | for tja_file in tja_files: 56 | print(f" - {tja_file}") 57 | print("\nThe following BIN files will be REPAIRED:") 58 | for bin_file in bin_files: 59 | print(f" - {bin_file}") 60 | choice = input("\nDo you wish to continue? [y/n]") 61 | if choice.lower() != "y": 62 | sys.exit("'y' not selected, exiting.") 63 | print() 64 | files = tja_files + bin_files 65 | 66 | elif os.path.isfile(path_input): 67 | files = [path_input] 68 | else: 69 | raise FileNotFoundError("No such file or directory: " + path_input) 70 | 71 | for file in files: 72 | process_file(file) 73 | 74 | 75 | def parse_files(directory: str) -> Tuple[List[str], List[str]]: 76 | """Find all or .bin files within a directory.""" 77 | tja_files, bin_files = [], [] 78 | for root, _, files in os.walk(directory): 79 | for file in files: 80 | if file.endswith(".tja"): 81 | tja_files.append(os.path.join(root, file)) 82 | elif file.endswith(".bin"): 83 | if file.startswith("song_"): 84 | print(f"Skipping '{file}' because it starts with 'song_' " 85 | f"(probably an audio file, not a chart file).") 86 | continue 87 | bin_files.append(os.path.join(root, file)) 88 | return tja_files, bin_files 89 | 90 | 91 | def process_file(fname: str) -> None: 92 | """Process a single file path (TJA or BIN).""" 93 | if fname.endswith(".bin"): 94 | print(f"Repairing {fname}") 95 | repair_bin(fname) 96 | else: 97 | print(f"Converting {fname}") 98 | # Parse lines in TJA file 99 | parsed_tja = parse_tja(fname) 100 | 101 | # Convert parsed TJA courses and write each course to `.bin` files 102 | base_name = os.path.splitext(fname)[0] 103 | for course_name, course in parsed_tja.courses.items(): 104 | convert_and_write(course, course_name, base_name, 105 | single_course=len(parsed_tja.courses) == 1) 106 | 107 | 108 | def convert_and_write(tja_data: TJACourse, 109 | course_name: str, 110 | base_name: str, 111 | single_course: bool = False) -> None: 112 | """Process the parsed data for a single TJA course.""" 113 | fumen_data = convert_tja_to_fumen(tja_data) 114 | # fix don/ka types 115 | fix_dk_note_types_course(fumen_data) 116 | # Add course ID (e.g. '_x', '_x_1', '_x_2') to the output file's base name 117 | output_name = base_name 118 | if single_course: 119 | pass # Replicate tja2bin.exe behavior by excluding course ID 120 | else: 121 | split_name = course_name.split("P") # e.g. 'OniP2' -> ['Oni', '2'] 122 | output_name += f"_{COURSE_IDS[split_name[0]]}" 123 | if len(split_name) == 2: 124 | output_name += f"_{split_name[1]}" # Add "_1"/"_2" if P1/P2 chart 125 | write_fumen(f"{output_name}.bin", fumen_data) 126 | 127 | 128 | def repair_bin(fname_bin: str) -> None: 129 | """Repair the don/ka types of an existing .bin file.""" 130 | fumen_data = parse_fumen(fname_bin) 131 | # fix timing windows 132 | for course, course_id in COURSE_IDS.items(): 133 | if any(fname_bin.endswith(f"_{i}.bin") 134 | for i in [course_id, f"{course_id}_1", f"{course_id}_2"]): 135 | print(f" - Setting {course} timing windows...") 136 | fumen_data.header.set_timing_windows(difficulty=course) 137 | break 138 | else: 139 | print(f" - Can't infer difficulty {list(COURSE_IDS.values())} from " 140 | f"filename. Skipping timing window fix...") 141 | 142 | # fix don/ka types 143 | print(" - Fixing don/ka note types (do/ko/don, ka/kat)...") 144 | fix_dk_note_types_course(fumen_data) 145 | # write repaired fumen 146 | shutil.move(fname_bin, fname_bin+".bak") 147 | write_fumen(fname_bin, fumen_data) 148 | 149 | 150 | # NB: This entry point is necessary for the Pyinstaller executable 151 | if __name__ == "__main__": 152 | main() 153 | -------------------------------------------------------------------------------- /.github/workflows/test_and_publish_release.yml: -------------------------------------------------------------------------------- 1 | #file: noinspection LongLine 2 | name: "Test and publish release" 3 | 4 | on: 5 | workflow_dispatch: 6 | inputs: 7 | release_version: 8 | description: 'Release version number' 9 | required: true 10 | push: 11 | branches: 12 | - main 13 | pull_request: 14 | branches: 15 | - '*' 16 | 17 | env: 18 | PY_COLORS: "1" 19 | 20 | jobs: 21 | test-and-publish-release: 22 | runs-on: windows-2019 23 | steps: 24 | - name: Checkout tja2fumen (main branch) 25 | uses: actions/checkout@v3 26 | 27 | - name: Set up Python 28 | uses: actions/setup-python@v4 29 | with: 30 | python-version: '3.8.x' 31 | 32 | - name: Install tja2fumen and its dev dependencies 33 | run: | 34 | pip install -e .[dev] 35 | 36 | - name: Run tests (Python API) 37 | run: | 38 | pytest testing --entry-point python-api 39 | 40 | # The GitHub Actions bot email was taken from: https://github.community/t/github-actions-bot-email-address/17204/6 41 | - name: Set bot user data for commits 42 | # Only set git user data if workflow is run manually. (This allows the other steps in the workflow to test PRs.) 43 | if: github.event_name == 'workflow_dispatch' 44 | run: | 45 | git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" 46 | git config --global user.name "GitHub Actions Bot" 47 | 48 | - name: Update pyproject.toml version (for release) 49 | # Only update the version number if workflow is run manually. (This allows the other steps in the workflow to test PRs.) 50 | if: github.event_name == 'workflow_dispatch' 51 | run: | 52 | toml set --toml-path pyproject.toml project.version "${{ github.event.inputs.release_version }}" 53 | git add pyproject.toml 54 | git commit -m "Update pyproject.toml version for ${{ github.event.inputs.release_version }}" 55 | 56 | - name: Build wheel/sdist 57 | run: python -m build 58 | 59 | - name: Uninstall editable tja2fumen and install built wheel 60 | shell: bash 61 | run: | 62 | pip uninstall tja2fumen -y 63 | pip install dist/*.whl 64 | 65 | - name: Run tests (installed wheel) 66 | run: pytest testing --entry-point python-cli 67 | 68 | - name: Add UPX to the PATH 69 | uses: crazy-max/ghaction-upx@v2 70 | with: 71 | install-only: true 72 | 73 | - name: Build pyinstaller executable 74 | run: | 75 | pyinstaller src\tja2fumen\__init__.py ` 76 | --name tja2fumen-${{ github.event.inputs.release_version }} ` 77 | --add-data="src\tja2fumen\hp_values.csv;tja2fumen\" ` 78 | --onefile ` 79 | --exclude-module bz2 ` 80 | --exclude-module hashlib ` 81 | --exclude-module lzma ` 82 | --exclude-module socket ` 83 | --exclude-module ssl ` 84 | --exclude-module unicodedata ` 85 | --exclude-module select 86 | 87 | - name: Run tests (installed wheel) 88 | run: pytest testing --entry-point exe 89 | 90 | - name: Push release changes 91 | # Only push the new tags if workflow is run manually. (This allows the other steps in the workflow to test PRs.) 92 | if: github.event_name == 'workflow_dispatch' 93 | run: | 94 | git tag ${{ github.event.inputs.release_version }} 95 | git push --tags 96 | 97 | - uses: ncipollo/release-action@v1 98 | # Only create release if workflow is run manually. (This allows the other steps in the workflow to test PRs.) 99 | if: github.event_name == 'workflow_dispatch' 100 | name: Create release 101 | id: create_release 102 | with: 103 | tag: ${{ github.event.inputs.release_version }} 104 | token: ${{ secrets.GITHUB_TOKEN }} 105 | artifacts: "dist/tja2fumen-${{ github.event.inputs.release_version }}.exe,\ 106 | dist/tja2fumen-${{ github.event.inputs.release_version }}.tar.gz,\ 107 | dist/tja2fumen-${{ github.event.inputs.release_version }}-py3-none-any.whl" 108 | draft: true 109 | 110 | - name: Publish distribution to PyPI 111 | # Only publish distribution if workflow is run manually. (This allows the other steps in the workflow to test PRs.) 112 | if: github.event_name == 'workflow_dispatch' 113 | run: twine upload dist/*.whl dist/*.tar.gz --username __token__ --password ${{ secrets.PYPI_API_TOKEN }} 114 | 115 | build-for-linux: 116 | needs: test-and-publish-release 117 | runs-on: ubuntu-latest 118 | steps: 119 | - name: Checkout tja2fumen (main branch) 120 | uses: actions/checkout@v3 121 | 122 | - name: Set up Python 123 | uses: actions/setup-python@v4 124 | with: 125 | python-version: '3.8.x' 126 | 127 | - name: Install tja2fumen and its dev dependencies 128 | run: | 129 | pip install -e .[dev] 130 | 131 | - name: Add UPX to the PATH 132 | uses: crazy-max/ghaction-upx@v2 133 | with: 134 | install-only: true 135 | 136 | - name: Build pyinstaller executable 137 | run: | 138 | pyinstaller src/tja2fumen/__init__.py \ 139 | --name tja2fumen-${{ github.event.inputs.release_version }} \ 140 | --add-data="src/tja2fumen/hp_values.csv:tja2fumen/" \ 141 | --onefile \ 142 | --exclude-module bz2 \ 143 | --exclude-module hashlib \ 144 | --exclude-module lzma \ 145 | --exclude-module socket \ 146 | --exclude-module ssl \ 147 | --exclude-module unicodedata \ 148 | --exclude-module select 149 | 150 | - uses: ncipollo/release-action@v1 151 | # Only create release if workflow is run manually. (This allows the other steps in the workflow to test PRs.) 152 | if: github.event_name == 'workflow_dispatch' 153 | name: Create release 154 | id: create_release 155 | with: 156 | tag: ${{ github.event.inputs.release_version }} 157 | token: ${{ secrets.GITHUB_TOKEN }} 158 | artifacts: "dist/tja2fumen-${{ github.event.inputs.release_version }}" 159 | allowUpdates: true 160 | draft: true 161 | -------------------------------------------------------------------------------- /testing/data/clsca.tja: -------------------------------------------------------------------------------- 1 | BPM:120.26 2 | OFFSET:-2.024 3 | 4 | 5 | COURSE:Oni 6 | LEVEL:7 7 | 8 | 9 | STYLE:Single 10 | BALLOON:30,10, 11 | SCOREINIT:570 12 | SCOREDIFF:147 13 | 14 | 15 | #START 16 | 17 | 18 | #GOGOSTART 19 | 1011111210111112, 20 | #BPMCHANGE 119 21 | 1011211210003000, 22 | #BPMCHANGE 120 23 | 1011111210111112, 24 | 1022202220000000, 25 | 1011111210111112, 26 | #BPMCHANGE 120.69 27 | 1011211210003000, 28 | #BPMCHANGE 119.94 29 | 1011111210111112, 30 | #BPMCHANGE 118.83 31 | #SCROLL 1.01 32 | 1011101110003000, 33 | 34 | #BPMCHANGE 120.06 35 | #SCROLL 1 36 | #GOGOEND 37 | 1010202010111020, 38 | 1010202010111000, 39 | 1010202010111020, 40 | 1010202010111000, 41 | 42 | #BPMCHANGE 118.34 43 | 2220222022202220, 44 | #BPMCHANGE 122.22 45 | #SCROLL 0.97 46 | 21121210, 47 | #BPMCHANGE 119.94 48 | #SCROLL 0.99 49 | 2220222022202220, 50 | #SCROLL 1 51 | 7, 52 | #BPMCHANGE 120.57 53 | 0008, 54 | 55 | #BPMCHANGE 120 56 | #GOGOSTART 57 | 1011111210111112, 58 | 1011211210003000, 59 | 1011111210111112, 60 | 1022202220000000, 61 | 1011111210111112, 62 | 1011211210003000, 63 | 1011111210111112, 64 | #BPMCHANGE 118.86 65 | 1011101110003000, 66 | 67 | #BPMCHANGE 120.26 68 | #GOGOEND 69 | 1122, 70 | 1122, 71 | 72 | #BPMCHANGE 120 73 | 100102200100, 74 | 201101100200, 75 | 100102200200, 76 | 200101100200, 77 | 10120121, 78 | 21121000, 79 | 101202201202, 80 | 2000222022202220, 81 | 82 | 2011101010101020, 83 | 1022201010222010, 84 | 1011102020002000, 85 | #BPMCHANGE 117.99 86 | 2011111122222222, 87 | 88 | #BPMCHANGE 122.08 89 | #SCROLL 0.97 90 | #GOGOSTART 91 | 100102200100, 92 | #BPMCHANGE 120 93 | #SCROLL 1 94 | 201101100200, 95 | 100102200200, 96 | #BPMCHANGE 119.3 97 | 200101100200, 98 | 99 | #BPMCHANGE 120 100 | #GOGOEND 101 | 10120121, 102 | 21121000, 103 | 101202201202, 104 | #BPMCHANGE 121.03 105 | 2000222022202220, 106 | 107 | #BPMCHANGE 120 108 | 2011101010101020, 109 | 1022201010222010, 110 | 1011102020002000, 111 | 112 | #GOGOSTART 113 | 1011111210111112, 114 | 1011211210003000, 115 | 1011111210111112, 116 | 1022202220000000, 117 | 1011111210111112, 118 | 1011211210003000, 119 | 1011111210111112, 120 | 1112111211121112, 121 | 122 | 70000081, 123 | 1300, 124 | 125 | #GOGOEND 126 | 127 | 128 | #END 129 | 130 | 131 | COURSE:Hard 132 | LEVEL:5 133 | BALLOON:25,10 134 | SCOREINIT:550 135 | SCOREDIFF:155 136 | 137 | 138 | STYLE:Single 139 | 140 | 141 | #START 142 | 143 | 144 | #GOGOSTART 145 | 1011101010111010, 146 | #BPMCHANGE 119 147 | 1011101110003000, 148 | #BPMCHANGE 120 149 | 1011101010111010, 150 | 1022202220000000, 151 | 1011101010111010, 152 | #BPMCHANGE 120.69 153 | 1011101110003000, 154 | #BPMCHANGE 119.94 155 | 1011101010111010, 156 | #BPMCHANGE 118.83 157 | #SCROLL 1.01 158 | 1011101110003000, 159 | 160 | #BPMCHANGE 120.06 161 | #SCROLL 1 162 | #GOGOEND 163 | 11221110, 164 | 1010202010111000, 165 | 11221110, 166 | 1010202010111000, 167 | 168 | #BPMCHANGE 118.34 169 | 2220222022202220, 170 | #BPMCHANGE 122.22 171 | #SCROLL 0.97 172 | 11121120, 173 | #BPMCHANGE 119.94 174 | #SCROLL 0.99 175 | 2220222022202220, 176 | #SCROLL 1 177 | 7, 178 | #BPMCHANGE 120.57 179 | 0008, 180 | 181 | #BPMCHANGE 120 182 | #GOGOSTART 183 | 1011101010111010, 184 | 1011101110003000, 185 | 1011101010111010, 186 | 1022202220000000, 187 | 1011101010111010, 188 | 1011101110003000, 189 | 1011101010111010, 190 | #BPMCHANGE 118.86 191 | 1011101110003000, 192 | 193 | #BPMCHANGE 120.26 194 | #GOGOEND 195 | , 196 | 1122, 197 | 198 | #BPMCHANGE 120 199 | 100102200100, 200 | 201101100000, 201 | 100102200000, 202 | 200101100000, 203 | 10120112, 204 | 11111000, 205 | 100100200202, 206 | 2, 207 | 208 | 20101110, 209 | 10211021, 210 | 10211020, 211 | #BPMCHANGE 117.99 212 | 200000000000500000000000000000000008000000000000, 213 | 214 | #BPMCHANGE 122.08 215 | #SCROLL 0.97 216 | #GOGOSTART 217 | 200102200100, 218 | #BPMCHANGE 120 219 | #SCROLL 1 220 | 201101100000, 221 | 100102200000, 222 | #BPMCHANGE 119.3 223 | 200101100000, 224 | 225 | #BPMCHANGE 120 226 | #GOGOEND 227 | 10120112, 228 | 11111000, 229 | 100100200202, 230 | #BPMCHANGE 121.03 231 | 2, 232 | 233 | #BPMCHANGE 120 234 | 20101110, 235 | 10211021, 236 | 10211020, 237 | 238 | #GOGOSTART 239 | 1011101010111010, 240 | 1011101110003000, 241 | 1011101010111010, 242 | 1022202220000000, 243 | 1011101010111010, 244 | 1011101110003000, 245 | 1011101010111010, 246 | 1110111011101110, 247 | 248 | 70000081, 249 | 1300, 250 | 251 | #GOGOEND 252 | 253 | 254 | #END 255 | 256 | 257 | COURSE:Normal 258 | LEVEL:5 259 | BALLOON:20,7 260 | SCOREINIT:680 261 | SCOREDIFF:207 262 | 263 | 264 | STYLE:Single 265 | 266 | 267 | #START 268 | 269 | 270 | #GOGOSTART 271 | 1111, 272 | #BPMCHANGE 119 273 | 11101000, 274 | #BPMCHANGE 120 275 | 1111, 276 | 11101000, 277 | 1111, 278 | #BPMCHANGE 120.69 279 | 11101000, 280 | #BPMCHANGE 119.94 281 | 11101110, 282 | #BPMCHANGE 118.83 283 | #SCROLL 1.01 284 | 10111030, 285 | 286 | #BPMCHANGE 120.06 287 | #SCROLL 1 288 | #GOGOEND 289 | 10201110, 290 | 10201110, 291 | 10201110, 292 | 10201110, 293 | 294 | #BPMCHANGE 118.34 295 | 22202220, 296 | #BPMCHANGE 122.22 297 | #SCROLL 0.97 298 | 11101210, 299 | #BPMCHANGE 119.94 300 | #SCROLL 0.99 301 | 22202220, 302 | #SCROLL 1 303 | 7, 304 | #BPMCHANGE 120.57 305 | 0008, 306 | 307 | #BPMCHANGE 120 308 | #GOGOSTART 309 | 1111, 310 | 11111020, 311 | 1111, 312 | 11111000, 313 | 1111, 314 | 11111020, 315 | 11101110, 316 | #BPMCHANGE 118.86 317 | 10111030, 318 | 319 | #BPMCHANGE 120.26 320 | #GOGOEND 321 | , 322 | 1122, 323 | 324 | #BPMCHANGE 120 325 | 1122, 326 | 2110, 327 | 1122, 328 | 2110, 329 | 10110011, 330 | 10112000, 331 | 10222020, 332 | 20222020, 333 | 334 | 20101110, 335 | 12101000, 336 | 00121020, 337 | #BPMCHANGE 117.99 338 | 200000000000500000000000000000000008000000000000, 339 | 340 | #BPMCHANGE 122.08 341 | #SCROLL 0.97 342 | #GOGOSTART 343 | 1122, 344 | #BPMCHANGE 120 345 | #SCROLL 1 346 | 2110, 347 | 1122, 348 | #BPMCHANGE 119.3 349 | 2110, 350 | 351 | #BPMCHANGE 120 352 | #GOGOEND 353 | 10110011, 354 | 10112000, 355 | 10222020, 356 | #BPMCHANGE 121.03 357 | 20222020, 358 | 359 | #BPMCHANGE 120 360 | 20101110, 361 | 12101000, 362 | 00121020, 363 | 364 | #GOGOSTART 365 | 11101110, 366 | 11111020, 367 | 11101110, 368 | 11111000, 369 | 11101110, 370 | 11111020, 371 | 11101110, 372 | 12121212, 373 | 70000081, 374 | 1300, 375 | 376 | #GOGOEND 377 | 378 | 379 | #END 380 | 381 | 382 | COURSE:Easy 383 | LEVEL:3 384 | BALLOON: 385 | SCOREINIT:660 386 | SCOREDIFF:270 387 | 388 | 389 | STYLE:Single 390 | 391 | 392 | #START 393 | 394 | 395 | #GOGOSTART 396 | 11, 397 | #BPMCHANGE 119 398 | 1110, 399 | #BPMCHANGE 120 400 | 11, 401 | 1110, 402 | 22, 403 | #BPMCHANGE 120.69 404 | 2220, 405 | #BPMCHANGE 119.94 406 | 11, 407 | #BPMCHANGE 118.83 408 | #SCROLL 1.01 409 | 1110, 410 | 411 | #BPMCHANGE 120.06 412 | #SCROLL 1 413 | #GOGOEND 414 | 1210, 415 | 1210, 416 | 1210, 417 | 1210, 418 | 419 | #BPMCHANGE 118.34 420 | 2220, 421 | #BPMCHANGE 122.22 422 | #SCROLL 0.97 423 | 1110, 424 | #BPMCHANGE 119.94 425 | #SCROLL 0.99 426 | 2220, 427 | #SCROLL 1 428 | 5, 429 | #BPMCHANGE 120.57 430 | 000000000000000000000008000000000000000000000000, 431 | 432 | #BPMCHANGE 120 433 | #GOGOSTART 434 | 11, 435 | 1110, 436 | 11, 437 | 1110, 438 | 22, 439 | 2220, 440 | 11, 441 | #BPMCHANGE 118.86 442 | 1113, 443 | 444 | #BPMCHANGE 120.26 445 | #GOGOEND 446 | , 447 | 12, 448 | 449 | #BPMCHANGE 120 450 | 1120, 451 | 2110, 452 | 1120, 453 | 2110, 454 | 1, 455 | 1120, 456 | 12, 457 | 22, 458 | 459 | 2011, 460 | 1011, 461 | 1011, 462 | #BPMCHANGE 117.99 463 | 200000000000500000000000000000000008000000000000, 464 | 465 | #BPMCHANGE 122.08 466 | #SCROLL 0.97 467 | #GOGOSTART 468 | 1120, 469 | #BPMCHANGE 120 470 | #SCROLL 1 471 | 2110, 472 | 1120, 473 | #BPMCHANGE 119.3 474 | 2110, 475 | 476 | #BPMCHANGE 120 477 | #GOGOEND 478 | 1, 479 | 1120, 480 | 12, 481 | #BPMCHANGE 121.03 482 | 22, 483 | 484 | #BPMCHANGE 120 485 | 2011, 486 | 1011, 487 | 1011, 488 | 489 | #GOGOSTART 490 | 31, 491 | 1110, 492 | 31, 493 | 1110, 494 | 42, 495 | 2220, 496 | 33, 497 | 1111, 498 | 499 | 500000000000000000000000000008000000000000100000, 500 | 1300, 501 | 502 | #GOGOEND 503 | 504 | 505 | #END -------------------------------------------------------------------------------- /testing/data/mikdp.tja: -------------------------------------------------------------------------------- 1 | // This is a basic song with notes, balloons, and drumrolls. 2 | // It does not feature BPMCHANGEs, branches, or multiplayer commands. 3 | BPM:181 4 | OFFSET:-1.99 5 | 6 | 7 | 8 | COURSE:Oni 9 | LEVEL:10 10 | BALLOON: 11 | SCOREINIT:380 12 | SCOREDIFF:92 13 | 14 | #START 15 | 1111111111112000, 16 | 17 | #GOGOSTART 18 | 1020112010212012, 19 | 1020112012212011, 20 | 1111201122101222, 21 | 100000200000100200200100100000202020100000200000, 22 | 23 | #GOGOEND 24 | 1111, 25 | 1000100010001011, 26 | 1110201110201110, 27 | 2011102011111111, 28 | 1001201011102012, 29 | 1011201002 30 | 102010, 31 | 1001201011102012, 32 | 1011201002 33 | 112022, 34 | 10012010111020 35 | 12, 36 | 1011201122112211, 37 | 38 | #GOGOSTART 39 | 1020112010212012, 40 | 10201120 41 | 12212011, 42 | 43 | #GOGOEND 44 | 1011201011102012, 45 | 101120100 46 | 2102010, 47 | 1011221122102012, 48 | 101120100 49 | 2112022, 50 | 100120101110 51 | 2012, 52 | 1011201122112222, 53 | 54 | #GOGOSTART 55 | 1020112010212012, 56 | 1020112012212010, 57 | 58 | #GOGOEND 59 | 1110101111101011, 60 | 11101011111010 61 | 11, 62 | 11101011 63 | 11101011, 64 | 1110 65 | 10111110 66 | 2011, 67 | 10211021 68 | 10211021, 69 | 1021102110112011, 70 | 1202222210222222, 71 | 100000000300000000300000600000000000008000000000, 72 | 300300 73 | 3030000000, 74 | 75 | #GOGOSTART 76 | 10221020 77 | 11201022, 78 | 102011201022 79 | 1020, 80 | 10212012102010 81 | 22, 82 | 112010221020 83 | 1120, 84 | 12121021212010 85 | 22, 86 | 1020112010221020, 87 | 1122105000000000, 88 | 000000000008000000000000 89 | 200200200200100100100100, 90 | 20112010 91 | 22102011, 92 | 201022102011 93 | 2010, 94 | 20121021201020 95 | 11, 96 | 2210201120102210, 97 | 212120 98 | 12121020 99 | 11, 100 | 20112211221112 101 | 10, 102 | 3004003030040030, 103 | 104 | #GOGOEND 105 | 3232 106 | 3020, 107 | 108 | #GOGOSTART 109 | 1020112010212012, 110 | 1020112012212011, 111 | 1111201122101222, 112 | 100000200000100200200100100000202020100000200000, 113 | 1020112010212012, 114 | 1020112012212011, 115 | 1111201122101222, 116 | 100000200000100200200100 117 | 100000202020100000200000, 118 | 119 | #GOGOEND 120 | 3000 121 | 0003, 122 | 000022111030 123 | 0300, 124 | 3000000 125 | 4, 126 | 000012221222 127 | 1222, 128 | 11111111111111 129 | 11, 130 | 1111111111111111, 131 | 0000000000300300, 132 | 30221222 133 | 11112222, 134 | 135 | #GOGOSTART 136 | 10221020 137 | 11201022, 138 | 102011201022 139 | 1020, 140 | 10212012102010 141 | 22, 142 | 11201022102011 143 | 20, 144 | 121210 145 | 21212010 146 | 22, 147 | 10221122112212 148 | 11, 149 | 1021021010210210, 150 | 151 | #GOGOEND 152 | 302030203011 153 | 2210, 154 | 40104010 155 | 40221000, 156 | 157 | #GOGOSTART 158 | 1020112010212012, 159 | 1020112012212011, 160 | 1111201122101222, 161 | 100000200000100200200100100000202020100000200000, 162 | 1020112211212012, 163 | 1022112212212011, 164 | 1111201122101222, 165 | 100100200200100200200100100000202020100000200000, 166 | 167 | #GOGOEND 168 | , 169 | 170 | #MEASURE 2/4 171 | , 172 | 173 | #BARLINEOFF 174 | #SCROLL 2 175 | 0300, 176 | 177 | #MEASURE 4/4 178 | , 179 | , 180 | 181 | #END 182 | 183 | 184 | 185 | COURSE:Hard 186 | LEVEL:7 187 | BALLOON:21,11 188 | SCOREINIT:500 189 | SCOREDIFF:130 190 | 191 | #START 192 | , 193 | 194 | #GOGOSTART 195 | 1010200010111000, 196 | 1010200010111000, 197 | 1010201011101000, 198 | 1010200020222020, 199 | 200 | #GOGOEND 201 | 1, 202 | , 203 | 7, 204 | 0008, 205 | 10201122, 206 | 02010221, 207 | 10201122, 208 | 02010221, 209 | 10222011, 210 | 10221120, 211 | 212 | #GOGOSTART 213 | 1010200010111000, 214 | 1010200010111000, 215 | 216 | #GOGOEND 217 | 10201122, 218 | 02010221, 219 | 10201122, 220 | 02010221, 221 | 10222011, 222 | 10221120, 223 | 224 | #GOGOSTART 225 | 1010200010111000, 226 | 1010200010111000, 227 | 228 | #GOGOEND 229 | 11011101, 230 | 11011101, 231 | 11011101, 232 | 11011020, 233 | 12121212, 234 | 12121220, 235 | 3003003040040040, 236 | 300000000300000000300000600000000000008000000000, 237 | 3003003030000000, 238 | 239 | #GOGOSTART 240 | 1011101010100010, 241 | 01122010, 242 | 1011101010100020, 243 | 02211020, 244 | 1010202011100010, 245 | 01212121, 246 | 2002005000000000, 247 | 000000000008000000000000200000000000200000000000, 248 | 1011101010100010, 249 | 01122010, 250 | 1011101010100020, 251 | 02211020, 252 | 1010202011100010, 253 | 21212120, 254 | 3003003040040040, 255 | 256 | #GOGOEND 257 | 3332, 258 | 259 | #GOGOSTART 260 | 1010200010111000, 261 | 1010200010111000, 262 | 1010201011101000, 263 | 1010200020222000, 264 | 1010200010111000, 265 | 1010200010111000, 266 | 1010201011101000, 267 | 1010200020222020, 268 | 269 | #GOGOEND 270 | 30000003, 271 | 0000000000300300, 272 | 30000007, 273 | 0008, 274 | 5, 275 | 000000000000000000000000000000000000000000000008, 276 | 0000000000300300, 277 | 600000000000008000000000200000000000200000000000, 278 | 279 | #GOGOSTART 280 | 1011101010100010, 281 | 01122010, 282 | 1011101010100020, 283 | 02211020, 284 | 1010202011100010, 285 | 21212120, 286 | 3003003040040040, 287 | 288 | #GOGOEND 289 | 300000000000300000000000600000000008000000000000, 290 | 3332, 291 | 292 | #GOGOSTART 293 | 1010200010111000, 294 | 1010200010111000, 295 | 1010201011101000, 296 | 1010200020222000, 297 | 1010200010111000, 298 | 1010200010111000, 299 | 1010201011101000, 300 | 1010200020222020, 301 | 302 | #GOGOEND 303 | , 304 | 305 | #MEASURE 2/4 306 | , 307 | 308 | #BARLINEOFF 309 | 0300, 310 | 311 | #MEASURE 4/4 312 | , 313 | , 314 | #END 315 | 316 | 317 | 318 | COURSE:Normal 319 | LEVEL:5 320 | BALLOON:14,15,7,6 321 | SCOREINIT:700 322 | SCOREDIFF:197 323 | 324 | #START 325 | , 326 | 327 | #GOGOSTART 328 | 10101110, 329 | 10101110, 330 | 2222, 331 | 500000000000000000000000000000000000000000000008, 332 | 333 | #GOGOEND 334 | , 335 | , 336 | 7, 337 | 0008, 338 | 10101001, 339 | 01010000, 340 | 10101001, 341 | 01010000, 342 | 1120, 343 | 1122, 344 | 345 | #GOGOSTART 346 | 10101110, 347 | 10101110, 348 | 349 | #GOGOEND 350 | 10101001, 351 | 01010000, 352 | 10101001, 353 | 01010000, 354 | 1120, 355 | 1122, 356 | 357 | #GOGOSTART 358 | 10101110, 359 | 10101110, 360 | 361 | #GOGOEND 362 | 1111, 363 | 1111, 364 | 1111, 365 | 1110, 366 | 2222, 367 | 2222, 368 | 9, 369 | 09, 370 | 8, 371 | 372 | #GOGOSTART 373 | 10101001, 374 | 01101000, 375 | 10101001, 376 | 01101000, 377 | 10101001, 378 | 01101010, 379 | 5, 380 | 000000000008000000000000000000000000000000000000, 381 | 10102001, 382 | 01101000, 383 | 10102001, 384 | 01101000, 385 | 10102001, 386 | 01101010, 387 | 44, 388 | 389 | #GOGOEND 390 | 3330, 391 | 392 | #GOGOSTART 393 | 10101110, 394 | 10101110, 395 | 2222, 396 | 500000000000000000000000000000000008000000000000, 397 | 10101110, 398 | 10101110, 399 | 2222, 400 | 500000000000000000000000000000000008000000000000, 401 | 402 | #GOGOEND 403 | 30000003, 404 | , 405 | 30000007, 406 | 0008, 407 | 5, 408 | 000000000000000000000000000000000000000000000008, 409 | 00000700, 410 | 00008000, 411 | 412 | #GOGOSTART 413 | 10102001, 414 | 01101000, 415 | 10102001, 416 | 01101000, 417 | 10102001, 418 | 01101010, 419 | 44, 420 | 421 | #GOGOEND 422 | 3330, 423 | 3330, 424 | 425 | #GOGOSTART 426 | 10101110, 427 | 10101110, 428 | 2222, 429 | 500000000000000000000000000000000008000000000000, 430 | 10101110, 431 | 10101110, 432 | 2222, 433 | 500000000000000000000000000000000000000000000008, 434 | 435 | #GOGOEND 436 | , 437 | 438 | #MEASURE 2/4 439 | , 440 | 441 | #BARLINEOFF 442 | 0300, 443 | 444 | #MEASURE 4/4 445 | , 446 | , 447 | 448 | #END 449 | 450 | 451 | 452 | COURSE:Easy 453 | LEVEL:3 454 | BALLOON:9,12,5 455 | SCOREINIT:610 456 | SCOREDIFF:210 457 | 458 | #START 459 | , 460 | 461 | #GOGOSTART 462 | 1110, 463 | 1110, 464 | 22, 465 | 500000000000000000000000000000000000000000000008, 466 | 467 | #GOGOEND 468 | , 469 | , 470 | 7, 471 | 00000800, 472 | 11, 473 | 1, 474 | 11, 475 | 1, 476 | 11, 477 | 22, 478 | 479 | #GOGOSTART 480 | 1110, 481 | 1110, 482 | 483 | #GOGOEND 484 | 11, 485 | 1, 486 | 11, 487 | 1, 488 | 11, 489 | 22, 490 | 491 | #GOGOSTART 492 | 1110, 493 | 1110, 494 | 495 | #GOGOEND 496 | 11, 497 | 11, 498 | 11, 499 | 1, 500 | 22, 501 | 22, 502 | 9, 503 | 09, 504 | 8, 505 | 506 | #GOGOSTART 507 | 11, 508 | 1110, 509 | 11, 510 | 1110, 511 | 11, 512 | 1110, 513 | 5, 514 | 000000000008000000000000000000000000000000000000, 515 | 12, 516 | 1110, 517 | 12, 518 | 1110, 519 | 12, 520 | 1110, 521 | 33, 522 | 523 | #GOGOEND 524 | 3330, 525 | 526 | #GOGOSTART 527 | 1110, 528 | 1110, 529 | 22, 530 | 500000000000000000000000000008000000000000000000, 531 | 1110, 532 | 1110, 533 | 22, 534 | 500000000000000000000000000008000000000000000000, 535 | 536 | #GOGOEND 537 | 30000003, 538 | , 539 | 30000003, 540 | , 541 | 5, 542 | 000000000000000000000000000000000000000000000008, 543 | 00000700, 544 | 00008000, 545 | 546 | #GOGOSTART 547 | 12, 548 | 1110, 549 | 12, 550 | 1110, 551 | 12, 552 | 1110, 553 | 33, 554 | 555 | #GOGOEND 556 | 3330, 557 | 3330, 558 | 559 | #GOGOSTART 560 | 1110, 561 | 1110, 562 | 22, 563 | 500000000000000000000000000008000000000000000000, 564 | 1110, 565 | 1110, 566 | 22, 567 | 500000000000000000000000000000000000000000000008, 568 | 569 | #GOGOEND 570 | , 571 | 572 | #MEASURE 2/4 573 | , 574 | 575 | #BARLINEOFF 576 | 0300, 577 | 578 | #MEASURE 4/4 579 | , 580 | , 581 | 582 | #END -------------------------------------------------------------------------------- /testing/data/butou5.tja: -------------------------------------------------------------------------------- 1 | BPM:148 2 | OFFSET:-1.84 3 | 4 | COURSE:Oni 5 | LEVEL:8 6 | BALLOON: 7 | SCOREINIT:410 8 | SCOREDIFF:100 9 | 10 | 11 | #START 12 | 13 | 14 | #MEASURE 5/4 15 | 500008000000000000000000000000000000000000000000000000000000, 16 | 17 | #MEASURE 4/4 18 | #BRANCHSTART r,1,2 19 | #N 20 | 3002202030022020, 21 | 3002202020000000, 22 | 1010101010102220, 23 | 1010222020000000, 24 | 12221222, 25 | 1020220220000000, 26 | 1010222010102220, 27 | 2202202020000000, 28 | 1011101010111010, 29 | 1002202010111020, 30 | 1002202020111010, 31 | 1002202022202000, 32 | 1011101010111010, 33 | 1002202010111020, 34 | 1022002200202000, 35 | 1020222010202220, 36 | 1011101010111010, 37 | 1002202010111020, 38 | 2220202020002000, 39 | 1002202010022020, 40 | 1011101010111010, 41 | 2202202010111020, 42 | 1010222010102220, 43 | 1020220220202000, 44 | 1010111110222000, 45 | 1010111120222000, 46 | 1010111220022000, 47 | 1022202012202000, 48 | 1010111220022000, 49 | 1010112210222000, 50 | 1010122110222000, 51 | 1000000011111010, 52 | #GOGOSTART 53 | 1011101010111010, 54 | 1002202010111020, 55 | 1002202010202020, 56 | 1020202022202000, 57 | 1011101010111010, 58 | 1002202010111020, 59 | 1002102020021022, 60 | 2020202020202022, 61 | 1011101010111010, 62 | 1022202010111020, 63 | 1022202010222020, 64 | 1020202020020020, 65 | 1011101010111010, 66 | 1022202010111020, 67 | 1002202012112011, 68 | 2020220220001000, 69 | #GOGOEND 70 | 12212222, 71 | 2020220220000000, 72 | 1010101010102220, 73 | 1020222010202000, 74 | 1002202010022020, 75 | 1010222020101000, 76 | 11111111, 77 | 33333000, 78 | 1022202220101022, 79 | 1022202220101022, 80 | 1022202220102220, 81 | 1110222011101000, 82 | 1022202011122020, 83 | 1010222011101000, 84 | 1120221011202210, 85 | 1122112211221122, 86 | 1002, 87 | #GOGOSTART 88 | 33, 89 | 3022202020000000, 90 | 1012202010122020, 91 | 1012202022202000, 92 | 33, 93 | 3022202010221010, 94 | 1012202010202000, 95 | 1022102210222220, 96 | 1011101010111010, 97 | 1022202010112020, 98 | 1022202010222020, 99 | 1022202020020020, 100 | 1011101010111010, 101 | 1022202010211010, 102 | 1111222211112222, 103 | 1122112030303000, 104 | 105 | #E 106 | 3002202030022020, 107 | 3002202020000000, 108 | 1011101020102220, 109 | 1010222020000000, 110 | 32223222, 111 | 3020220220000000, 112 | 1010222010102220, 113 | 1201202020000000, 114 | 1022202010201122, 115 | 1002202010221020, 116 | 1002202012102000, 117 | 1002202022102000, 118 | 1022202010202211, 119 | 1022202010221020, 120 | 1022002210202000, 121 | 1002202010022020, 122 | 1022202010201122, 123 | 1002202010221020, 124 | 1221202020011010, 125 | 1002202022122020, 126 | 1022202010202120, 127 | 1102202010221020, 128 | 1010222010102220, 129 | 1020220220201000, 130 | 3030000000212000, 131 | 3030000022212000, 132 | 3030000020022000, 133 | 1002202212102000, 134 | 3030000020022000, 135 | 3030000022202000, 136 | 3030000022212000, 137 | 1111222210022020, 138 | #GOGOSTART 139 | 1022202010201122, 140 | 1002202010221020, 141 | 1011202010112020, 142 | 1011202030303000, 143 | 1022202010201122, 144 | 1022202010221020, 145 | 3003003030111000, 146 | 34343434, 147 | 1022202010201122, 148 | 1002202010221020, 149 | 1011202010112020, 150 | 1011202022120020, 151 | 1022202010201122, 152 | 1022202010221020, 153 | 1012102102102000, 154 | 2020110110003000, 155 | #GOGOEND 156 | 11111111, 157 | 1010110110000000, 158 | 1010101010102220, 159 | 1010222020101000, 160 | 1002202010022020, 161 | 1010222022101000, 162 | 32223222, 163 | 32223000, 164 | 2021202122101000, 165 | 1012122122102000, 166 | 1012101222102220, 167 | 1221221122102000, 168 | 2011201122102000, 169 | 1011221122102000, 170 | 1221221012212210, 171 | 2211221122112211, 172 | 2004, 173 | #GOGOSTART 174 | 1022202010201122, 175 | 1002202010221020, 176 | 1002202020111000, 177 | 1002202011102000, 178 | 1022202010201122, 179 | 1002202010221020, 180 | 1002202011212000, 181 | 1022102210221111, 182 | 1022202010201122, 183 | 1022202010221020, 184 | 1011202010112020, 185 | 1011202022120020, 186 | 1022202010201122, 187 | 1022202010221020, 188 | 1221221112212211, 189 | 1221221110404000, 190 | 191 | #M 192 | 1002202010022020, 193 | 1002202010000000, 194 | 12221212, 195 | 1020122010000000, 196 | 12121212, 197 | 1020120210000000, 198 | 1010222010102220, 199 | 1201203040000000, 200 | 1011202020111020, 201 | 1011202020111010, 202 | 1011202020111010, 203 | 1022102210221010, 204 | 1011202020111020, 205 | 1011202010221020, 206 | 1011202010112020, 207 | 1011201120112020, 208 | 1112202020111020, 209 | 1112202020111010, 210 | 1112202020111010, 211 | 1022102210221010, 212 | 1112202020111020, 213 | 1112202010221020, 214 | 1012221010122210, 215 | 1012221210101000, 216 | 1010112210000000, 217 | 1010221120000000, 218 | 2020112210000000, 219 | 1002102012201000, 220 | 3030112210222000, 221 | 3030221120222000, 222 | 4040112210222000, 223 | 3000000011111000, 224 | #GOGOSTART 225 | 1011202020111020, 226 | 1011202020111010, 227 | 2212101022121010, 228 | 2212101010101000, 229 | 1011202020111020, 230 | 1011202010221020, 231 | 1021221010222020, 232 | 2012201220122010, 233 | 1112202020111020, 234 | 1112202020111010, 235 | 2210101022101010, 236 | 2210101012012010, 237 | 1112202020111020, 238 | 1112202010221020, 239 | 1021221021221020, 240 | 1012112210201000, 241 | #GOGOEND 242 | 12212222, 243 | 2020220210000002, 244 | 1020201020202220, 245 | 1020222010202000, 246 | 1002202010022020, 247 | 1010222022101000, 248 | 12212122, 249 | 12122000, 250 | 1011201122101000, 251 | 1011221122102000, 252 | 1022102211202010, 253 | 2211221120101000, 254 | 2011201122202000, 255 | 2011212122202000, 256 | 2222111122221111, 257 | 2211221122112211, 258 | 202020202020202220400000, 259 | #GOGOSTART 260 | 33, 261 | 3000000000112020, 262 | 1112202020111010, 263 | 1022102210221000, 264 | 33, 265 | 3000000000221020, 266 | 1112202010122020, 267 | 2010121012101210, 268 | 1112202020111020, 269 | 1112202020111010, 270 | 2210201022102010, 271 | 2210101012012010, 272 | 1112202020111020, 273 | 1112202010221020, 274 | 1111222211112222, 275 | 1111222030303000, 276 | 277 | #BRANCHEND 278 | #GOGOEND 279 | 280 | 281 | #END 282 | 283 | 284 | COURSE:Hard 285 | LEVEL:5 286 | BALLOON:14,16 287 | SCOREINIT:520 288 | SCOREDIFF:137 289 | 290 | 291 | #START 292 | 293 | 294 | #MEASURE 5/4 295 | , 296 | #MEASURE 4/4 297 | 1011100010111000, 298 | 10111000, 299 | 7, 300 | 00000800, 301 | 11101110, 302 | 1011101010000000, 303 | 7, 304 | 00000800, 305 | 1011100010001010, 306 | 1000000010111010, 307 | 1, 308 | 2022200020222000, 309 | 1011100010001010, 310 | 1000000010111010, 311 | 1, 312 | 1011100020222000, 313 | 1011100010001010, 314 | 1000000010111010, 315 | 1, 316 | 2022200020222000, 317 | 1011100010001010, 318 | 1000000010111010, 319 | 1, 320 | 1011100020222000, 321 | 1010111010000000, 322 | 1010111010000000, 323 | 1010222020000000, 324 | 11, 325 | 1010111010000000, 326 | 1010111010000000, 327 | 1010222020000000, 328 | 60000800, 329 | 330 | #GOGOSTART 331 | 1011101010001010, 332 | 1000000010111010, 333 | 1, 334 | 2022200020222000, 335 | 1011101010001010, 336 | 1000000010111010, 337 | 1, 338 | 1011100020222000, 339 | 1011101010001010, 340 | 1000000010111010, 341 | 1, 342 | 2022200020222000, 343 | 1011101010001010, 344 | 1000000010111010, 345 | 1, 346 | 1011100020222000, 347 | 348 | #GOGOEND 349 | 11022220, 350 | 11022220, 351 | 11022220, 352 | 11202220, 353 | 12201220, 354 | 11202000, 355 | 1111, 356 | 11111000, 357 | 2022202020002000, 358 | 2022202020002000, 359 | 22202220, 360 | 22222220, 361 | 2000200022202000, 362 | 2000200022202000, 363 | 22202220, 364 | 500000000000000000000000000000000000000000000008, 365 | 0, 366 | 367 | #GOGOSTART 368 | 30003011, 369 | 3000000010111010, 370 | 1, 371 | 2022200020222000, 372 | 30003011, 373 | 3000000010111010, 374 | 1, 375 | 1011100020222000, 376 | 1011101010001010, 377 | 1000000010111010, 378 | 1, 379 | 2022200020222000, 380 | 1011101010001010, 381 | 1000000010111010, 382 | 1110101011101010, 383 | 1110101030303000, 384 | 385 | #GOGOEND 386 | , 387 | , 388 | #END 389 | 390 | COURSE:Normal 391 | LEVEL:4 392 | BALLOON:10,12 393 | SCOREINIT:720 394 | SCOREDIFF:220 395 | 396 | #START 397 | #MEASURE 5/4 398 | , 399 | #MEASURE 4/4 400 | 11, 401 | 1110, 402 | 7, 403 | 00000800, 404 | 11, 405 | 1110, 406 | 7, 407 | 00000800, 408 | 10001011, 409 | 10001011, 410 | 1, 411 | 2220, 412 | 10001011, 413 | 10001011, 414 | 1, 415 | 2220, 416 | 10001011, 417 | 10001011, 418 | 1, 419 | 2220, 420 | 10001011, 421 | 10001011, 422 | 1, 423 | 22, 424 | 10111000, 425 | 10111000, 426 | 20222000, 427 | 11, 428 | 10111000, 429 | 10111000, 430 | 20222000, 431 | 60000800, 432 | 433 | #GOGOSTART 434 | 10001011, 435 | 10001011, 436 | 1, 437 | 2220, 438 | 10001011, 439 | 10001011, 440 | 1, 441 | 2220, 442 | 10001011, 443 | 10001011, 444 | 1, 445 | 2220, 446 | 10001011, 447 | 10001011, 448 | 1, 449 | 22, 450 | 451 | #GOGOEND 452 | 11000000, 453 | 11000000, 454 | 11000000, 455 | 11000000, 456 | 11, 457 | 11000000, 458 | 1111, 459 | 11101000, 460 | 2220, 461 | 2220, 462 | 2222, 463 | 22202000, 464 | 2220, 465 | 2220, 466 | 22202220, 467 | 500000000000000000000000000000000000000000000008, 468 | , 469 | 470 | #GOGOSTART 471 | 33, 472 | 3, 473 | 1212, 474 | 2220, 475 | 33, 476 | 3, 477 | 1212, 478 | 2220, 479 | 10001011, 480 | 1, 481 | 1212, 482 | 2220, 483 | 10001011, 484 | 11, 485 | 11101110, 486 | 11103030, 487 | 488 | #GOGOEND 489 | , 490 | , 491 | #END 492 | 493 | COURSE:Easy 494 | LEVEL:3 495 | BALLOON:8,10 496 | SCOREINIT:670 497 | SCOREDIFF:255 498 | 499 | #START 500 | #MEASURE 5/4 501 | , 502 | #MEASURE 4/4 503 | 11, 504 | 1, 505 | 7, 506 | 00000800, 507 | 11, 508 | 11, 509 | 7, 510 | 00000800, 511 | 1011, 512 | 1, 513 | 1, 514 | 2220, 515 | 1011, 516 | 1, 517 | 1, 518 | 2220, 519 | 1011, 520 | 1, 521 | 1, 522 | 2220, 523 | 1011, 524 | 1, 525 | 1, 526 | 2220, 527 | 1, 528 | 1, 529 | 3, 530 | 11, 531 | 1, 532 | 1, 533 | 3, 534 | 60000800, 535 | 536 | #GOGOSTART 537 | 1011, 538 | 1, 539 | 1, 540 | 2220, 541 | 1011, 542 | 1, 543 | 1, 544 | 2220, 545 | 1011, 546 | 1, 547 | 1, 548 | 2220, 549 | 1011, 550 | 1, 551 | 1, 552 | 2220, 553 | 554 | #GOGOEND 555 | 1, 556 | , 557 | 1, 558 | , 559 | 11, 560 | 1, 561 | 1111, 562 | 1110, 563 | 2220, 564 | 2220, 565 | 2222, 566 | 22, 567 | 2220, 568 | 2220, 569 | 2222, 570 | 500000000000000000000000000000000000000000000008, 571 | , 572 | 573 | #GOGOSTART 574 | 33, 575 | 3, 576 | 1, 577 | 2220, 578 | 33, 579 | 3, 580 | 1, 581 | 2220, 582 | 1011, 583 | 1, 584 | 1, 585 | 2220, 586 | 1011, 587 | 1, 588 | 11, 589 | 1033, 590 | 591 | #GOGOEND 592 | , 593 | , 594 | #END -------------------------------------------------------------------------------- /testing/data/shoto9.tja: -------------------------------------------------------------------------------- 1 | BPM:100 2 | OFFSET:-2.513 3 | 4 | COURSE:Oni 5 | LEVEL:9 6 | BALLOON:10,5,5,5,10 7 | SCOREINIT:400 8 | SCOREDIFF:95 9 | 10 | 11 | #START 12 | 13 | 14 | 100202100200100202102200, 15 | 100202100200000202102200, 16 | 100202100200100202122202, 17 | #BPMCHANGE 160 18 | #SCROLL 0.62 19 | 7008, 20 | #SCROLL 1 21 | 2000200020112210, 22 | 3001201002112210, 23 | 1001201002112211, 24 | 1001201002112210, 25 | 1021001002012222, 26 | 1001201002112210, 27 | 1001201002112211, 28 | 1001001001002210, 29 | 3000000022010020, 30 | 12022022, 31 | 500000000008000000200200100000000100000000100000, 32 | 2021002020102020, 33 | #BRANCHSTART r,5,6 34 | #N 35 | #LEVELHOLD 36 | 100000000100000000200000500000000008000000100200, 37 | 1000202210201120, 38 | #E 39 | 100000000100000000200000500000000008000000100200, 40 | 1000202210201120, 41 | #M 42 | 100000000100000000200000500000000008000000100200, 43 | 1000202210201120, 44 | #SECTION 45 | #BRANCHSTART r,7,8 46 | #BRANCHEND 47 | 500000000008000000200200100000200200200200200200, 48 | 1010202210201020, 49 | #SECTION 50 | #BRANCHSTART r,4,5 51 | #N 52 | 1001001070080000, 53 | 100 54 | #SCROLL 1 55 | 00 56 | #SCROLL 1 57 | 0 58 | #SCROLL 1 59 | 1 60 | #SCROLL 1 61 | 00 62 | #SCROLL 1 63 | 0 64 | #SCROLL 1 65 | 10200 66 | #SCROLL 1 67 | 0, 68 | #SCROLL 1 69 | 10 70 | #SCROLL 1 71 | 0 72 | #SCROLL 1 73 | 10 74 | #SCROLL 1 75 | 0 76 | #SCROLL 1 77 | 1 78 | #SCROLL 1 79 | 0 80 | #SCROLL 1 81 | 00 82 | #SCROLL 1 83 | 1020 84 | #SCROLL 1 85 | 0 86 | #SCROLL 1 87 | 0, 88 | #SCROLL 1 89 | 1 90 | #SCROLL 1 91 | 0 92 | #SCROLL 1 93 | 0 94 | #SCROLL 1 95 | 000 96 | #SCROLL 1 97 | 1 98 | #SCROLL 1 99 | 00 100 | #SCROLL 1 101 | 0 102 | #SCROLL 1 103 | 10200 104 | #SCROLL 1 105 | 0, 106 | #SCROLL 1 107 | 1001002000304000, 108 | 109 | #E 110 | 1001001070080000, 111 | 100 112 | #SCROLL 1.25 113 | 20 114 | #SCROLL 1.5 115 | 2 116 | #SCROLL 1 117 | 1 118 | #SCROLL 1.25 119 | 20 120 | #SCROLL 1.5 121 | 2 122 | #SCROLL 1 123 | 10200 124 | #SCROLL 1.25 125 | 1, 126 | #SCROLL 1 127 | 10 128 | #SCROLL 1.5 129 | 2 130 | #SCROLL 1 131 | 10 132 | #SCROLL 1.25 133 | 2 134 | #SCROLL 1 135 | 1 136 | #SCROLL 1.5 137 | 2 138 | #SCROLL 1.25 139 | 20 140 | #SCROLL 1 141 | 1020 142 | #SCROLL 1.25 143 | 2 144 | #SCROLL 1.5 145 | 1, 146 | #SCROLL 1 147 | 1 148 | #SCROLL 1.25 149 | 2 150 | #SCROLL 1.5 151 | 2 152 | #SCROLL 1.25 153 | 202 154 | #SCROLL 1 155 | 1 156 | #SCROLL 1.25 157 | 20 158 | #SCROLL 1.5 159 | 2 160 | #SCROLL 1 161 | 10200 162 | #SCROLL 1.25 163 | 1, 164 | #SCROLL 1 165 | 1001002000304000, 166 | 167 | #M 168 | 1001001070080000, 169 | 122 170 | #SCROLL 1 171 | 22 172 | #SCROLL 1 173 | 0 174 | #SCROLL 1.5 175 | 1 176 | #SCROLL 1.5 177 | 20 178 | #SCROLL 1.5 179 | 2 180 | #SCROLL 1.5 181 | 10212 182 | #SCROLL 1.5 183 | 0, 184 | #SCROLL 1.5 185 | 12 186 | #SCROLL 1.5 187 | 2 188 | #SCROLL 1.5 189 | 12 190 | #SCROLL 1.5 191 | 2 192 | #SCROLL 1.5 193 | 1 194 | #SCROLL 1.5 195 | 2 196 | #SCROLL 1.5 197 | 02 198 | #SCROLL 1.5 199 | 1022 200 | #SCROLL 1.5 201 | 2 202 | #SCROLL 1.5 203 | 2, 204 | #SCROLL 1.5 205 | 1 206 | #SCROLL 1.5 207 | 2 208 | #SCROLL 1.5 209 | 2 210 | #SCROLL 1.5 211 | 220 212 | #SCROLL 1.5 213 | 1 214 | #SCROLL 1.5 215 | 20 216 | #SCROLL 1.5 217 | 2 218 | #SCROLL 1.5 219 | 11212 220 | #SCROLL 1.5 221 | 2, 222 | #SCROLL 1.5 223 | 1221001000304000, 224 | 225 | #BRANCHSTART p,101,102 226 | #BRANCHEND 227 | 1020102210201022, 228 | 1022122010201022, 229 | 1000201110002011, 230 | 1010200010210010, 231 | 1022102010221020, 232 | 1100001100000000, 233 | 234 | #GOGOSTART 235 | 3021002010201120, 236 | 1021002010201122, 237 | 1020102210201020, 238 | 0020201022112211, 239 | 1021002010201120, 240 | 1021002010201122, 241 | 1022102010221120, 242 | 11110340, 243 | 1020112010201120, 244 | 1021012010201120, 245 | 1020112010201120, 246 | 0020201022112121, 247 | 1021012010221020, 248 | 3003003000000020, 249 | 1020112030030030, 250 | 0000002022020020, 251 | 252 | #GOGOEND 253 | 1001201000201121, 254 | 1001201000201122, 255 | 1001201002211212, 256 | 1001001000000000, 257 | #BPMCHANGE 200 258 | #SCROLL 0.8 259 | 3004, 260 | #SCROLL 1 261 | 1020112010120211, 262 | 1020112011210122, 263 | 1020112010120210, 264 | 1120112010221120, 265 | 1020112010120211, 266 | 1020112011211202, 267 | 1020112010112010, 268 | 1012221121112222, 269 | 1020112010120211, 270 | 1020112011211004, 271 | 0004000400000000, 272 | 1022102210222222, 273 | 1020112010112010, 274 | 1020101122222010, 275 | 2211102211112210, 276 | #BPMCHANGE 160 277 | #SCROLL 1.25 278 | 3, 279 | 280 | #SCROLL 1 281 | #GOGOSTART 282 | 3000000000100220, 283 | 30000122, 284 | 3020102210201020, 285 | 0020102211221212, 286 | 1021002010201120, 287 | 1021002010201120, 288 | 1022102010221212, 289 | 11110340, 290 | 1020112010201120, 291 | 1021012010201120, 292 | 1020112010201120, 293 | 0020201022112121, 294 | 1021012010221020, 295 | 3003003000000020, 296 | 1020112030030030, 297 | 0000002022020020, 298 | 299 | #GOGOEND 300 | 3001201002112210, 301 | 1001201002112212, 302 | 1001201002112210, 303 | 1021001002012222, 304 | 1001201002112210, 305 | 1001201002112212, 306 | 1001001001002210, 307 | 3700, 308 | 8300, 309 | 310 | 311 | #END 312 | 313 | 314 | COURSE:Hard 315 | LEVEL:7 316 | BALLOON:10,5,8 317 | SCOREINIT: 318 | SCOREDIFF: 319 | 320 | #START 321 | 100200000200100200102200, 322 | 100200000200100200102200, 323 | 100200000200100202200200, 324 | #MEASURE 5/8 325 | 70008, 326 | #BPMCHANGE 160 327 | #MEASURE 4/4 328 | 2000200020202220, 329 | 3001002002001110, 330 | 1001002002002220, 331 | 1001002002002220, 332 | 1001001001004000, 333 | 1001002002001110, 334 | 1001002002002220, 335 | 1001001001002220, 336 | 3, 337 | 30002022, 338 | 500000000008000000100100100000000000000000000000, 339 | 30022220, 340 | 500000000000000008000000300000000000000000000000, 341 | 0000300010201110, 342 | 1020102010202220, 343 | 1, 344 | 300000000300000000300000600000000000000008000000, 345 | 10010120, 346 | 1001001000102000, 347 | 10010120, 348 | 1001001000304000, 349 | 1000102010201110, 350 | 1000102010202220, 351 | 1000201110002011, 352 | 1010200040040040, 353 | 600000000000000000000000000000000008000000000000, 354 | 1100001100000000, 355 | 356 | #GOGOSTART 357 | 3000102010201110, 358 | 1000102010201110, 359 | 1000102010222010, 360 | 0020201022202220, 361 | 1000102010201110, 362 | 1000102010201110, 363 | 1022202010222020, 364 | 11110440, 365 | 1020111010201110, 366 | 1020111010201110, 367 | 1020111010222010, 368 | 0020201022202220, 369 | 1020111010202220, 370 | 3003003000000000, 371 | 1020111030030030, 372 | , 373 | 374 | #GOGOEND 375 | 1001002002001110, 376 | 1001002002002220, 377 | 1001002002002220, 378 | 1001007000000800, 379 | #BPMCHANGE 200 380 | #SCROLL 0.8 381 | 3, 382 | #SCROLL 1 383 | 10101110, 384 | 1000100010101110, 385 | 10101110, 386 | 1010111011101000, 387 | 10101110, 388 | 1000100010101110, 389 | 10101110, 390 | 1010111011101000, 391 | 10101110, 392 | 1000100011101000, 393 | , 394 | 1000100010101110, 395 | 10101110, 396 | 1000100011101000, 397 | 1010101010101110, 398 | #BPMCHANGE 160 399 | #SCROLL 1.25 400 | 3, 401 | 402 | #SCROLL 1 403 | #GOGOSTART 404 | 3000000000200200, 405 | 3002, 406 | 3000102010222010, 407 | 0020201022202220, 408 | 1000102010201110, 409 | 1000102010201110, 410 | 1022202010222020, 411 | 11110440, 412 | 1020111010201110, 413 | 1020111010201110, 414 | 1020111010222010, 415 | 0020201022202220, 416 | 1020111010201110, 417 | 3003003000000000, 418 | 1020111030030030, 419 | , 420 | 421 | #GOGOEND 422 | 3001002002001110, 423 | 1001002002002220, 424 | 1001002002002220, 425 | 1001001001004000, 426 | 1001002002001110, 427 | 1001002002002220, 428 | 1001002002002020, 429 | 3700, 430 | 8300, 431 | , 432 | #END 433 | 434 | COURSE:Normal 435 | LEVEL:6 436 | BALLOON:4 437 | SCOREINIT: 438 | SCOREDIFF: 439 | 440 | #START 441 | 0111, 442 | 500000000008000000100000000000000000000000000000, 443 | 0111, 444 | #MEASURE 5/8 445 | 500000000000000000000008000000, 446 | #BPMCHANGE 160 447 | #MEASURE 4/4 448 | , 449 | 10200120, 450 | 10200120, 451 | 10200120, 452 | 3003003003003000, 453 | 10200120, 454 | 10200120, 455 | 1111, 456 | 3, 457 | 3022, 458 | 500000000008000000000000300000000000000000000000, 459 | 1022, 460 | 500000000008000000000000300000000000000000000000, 461 | 1012, 462 | 100000100000200000000000500000000008000000000000, 463 | 1, 464 | 3003003030000000, 465 | 10010020, 466 | 10010220, 467 | 10010020, 468 | 10010340, 469 | 10121010, 470 | 10121010, 471 | 3434, 472 | 3000400040040040, 473 | 600000000000000000000000000000000008000000000000, 474 | 30030000, 475 | 476 | #GOGOSTART 477 | 10121210, 478 | 10121210, 479 | 10121212, 480 | 0440, 481 | 10121210, 482 | 10121210, 483 | 500000000000000008000000500000000000000008000000, 484 | 33330440, 485 | 12121210, 486 | 12121210, 487 | 12121222, 488 | 0440, 489 | 10121210, 490 | 3003003000000000, 491 | 1020100030030030, 492 | , 493 | 494 | #GOGOEND 495 | 10210120, 496 | 10210120, 497 | 10210120, 498 | 1001007000000800, 499 | #BPMCHANGE 200 500 | #SCROLL 0.8 501 | 3, 502 | #SCROLL 1 503 | 10001110, 504 | 11101010, 505 | 10001110, 506 | 11111110, 507 | 10001110, 508 | 11101010, 509 | 10001110, 510 | 3333, 511 | 10001110, 512 | 11101010, 513 | , 514 | 3333, 515 | 10001110, 516 | 10001110, 517 | 1111, 518 | #BPMCHANGE 160 519 | #SCROLL 1.25 520 | 3, 521 | 522 | #SCROLL 1 523 | #GOGOSTART 524 | 30000400, 525 | 3004, 526 | 10121212, 527 | 0440, 528 | 10121210, 529 | 10121210, 530 | 500000000000000008000000500000000000000008000000, 531 | 33330440, 532 | 12121210, 533 | 12121210, 534 | 12121222, 535 | 0440, 536 | 10121210, 537 | 3003003000000000, 538 | 1020100030030030, 539 | , 540 | 541 | #GOGOEND 542 | 10210120, 543 | 10210120, 544 | 10210120, 545 | 3003003003003000, 546 | 10210120, 547 | 10210120, 548 | 1111, 549 | 3, 550 | 0300, 551 | , 552 | #END 553 | 554 | COURSE:Easy 555 | LEVEL:4 556 | BALLOON:5,8,4,5 557 | SCOREINIT: 558 | SCOREDIFF: 559 | 560 | #START 561 | 11, 562 | 500000000000000000000008000000000000000000000000, 563 | 11, 564 | #MEASURE 5/8 565 | 500000000000000000000008000000, 566 | #BPMCHANGE 160 567 | #MEASURE 4/4 568 | , 569 | 1011, 570 | 1011, 571 | 1011, 572 | 500000000000000000000000000008000000000000000000, 573 | 1011, 574 | 1011, 575 | 1011, 576 | 3, 577 | 1, 578 | 500000000000000000000000000008000000000000000000, 579 | 1, 580 | 500000000000000000000000000008000000000000000000, 581 | 11, 582 | 1110, 583 | 3, 584 | 70000800, 585 | 1, 586 | 12, 587 | 1, 588 | 14, 589 | 1011, 590 | 1022, 591 | 2303, 592 | 0300, 593 | 9009, 594 | 8, 595 | 596 | #GOGOSTART 597 | 1011, 598 | 1022, 599 | 20001005, 600 | 000000000000000000000000000008000000000000000000, 601 | 1011, 602 | 1022, 603 | 2022, 604 | 70000800, 605 | 1011, 606 | 1022, 607 | 20001005, 608 | 000000000000000000000000000008000000000000000000, 609 | 1011, 610 | 10030000, 611 | 10101003, 612 | , 613 | 614 | #GOGOEND 615 | 1, 616 | 12, 617 | 1, 618 | 10010000, 619 | #BPMCHANGE 200 620 | #SCROLL 0.8 621 | 3, 622 | #SCROLL 1 623 | 1, 624 | 1110, 625 | 1, 626 | 2220, 627 | 1, 628 | 1110, 629 | 1, 630 | 2222, 631 | 1, 632 | 1110, 633 | , 634 | 2222, 635 | 1, 636 | 1110, 637 | 70000800, 638 | #BPMCHANGE 160 639 | #SCROLL 1.25 640 | 3, 641 | 642 | #SCROLL 1 643 | #GOGOSTART 644 | 10000100, 645 | 1, 646 | 10001005, 647 | 000000000000000000000000000008000000000000000000, 648 | 1011, 649 | 1022, 650 | 2011, 651 | 10030000, 652 | 1011, 653 | 1022, 654 | 20001005, 655 | 000000000000000000000000000008000000000000000000, 656 | 1011, 657 | 10030000, 658 | 10102003, 659 | , 660 | 661 | #GOGOEND 662 | 1011, 663 | 1011, 664 | 1022, 665 | 500000000000000000000000000008000000000000000000, 666 | 1011, 667 | 1011, 668 | 1022, 669 | 3, 670 | 0300, 671 | , 672 | #END -------------------------------------------------------------------------------- /testing/data/senpac.tja: -------------------------------------------------------------------------------- 1 | BPM:160 2 | OFFSET:-1.705 3 | 4 | COURSE:Edit 5 | LEVEL:10 6 | 7 | STYLE:Double 8 | BALLOON:12 9 | SCOREINIT:430 10 | SCOREDIFF:112 11 | 12 | 13 | #START P1 14 | 15 | 16 | 10000201, 17 | 10100220, 18 | 1000002220002010, 19 | 1000100000111020, 20 | 10000201, 21 | 10100220, 22 | 1000222000200020, 23 | #MEASURE 2/4 24 | 1010, 25 | #MEASURE 4/4 26 | 300000000000000111200000, 27 | 1112121211121222, 28 | 1112121211211212, 29 | 1112111212211212, 30 | 1112111212121000, 31 | 1112121211121222, 32 | 1212111212121112, 33 | 1112111212221222, 34 | 1112111212121110, 35 | 3003003000303030, 36 | #MEASURE 2/4 37 | , 38 | #MEASURE 4/4 39 | 1010221010102210, 40 | 1010221020111020, 41 | 1010221010102210, 42 | 1010221010222220, 43 | 1010221010102210, 44 | 1010221020111020, 45 | 1010221010102210, 46 | 1000000010212121, 47 | 20011020, 48 | 1000001110100010, 49 | 10011020, 50 | 1000001110201000, 51 | 1020102210201011, 52 | 1020102210201011, 53 | 1020102210201011, 54 | 1022102121212111, 55 | 1000000030000022, 56 | 57 | #GOGOSTART 58 | 1010001010221020, 59 | 1022101110102000, 60 | 1110201010221020, 61 | 1000700000000800, 62 | 1020112010222000, 63 | 1020112010222000, 64 | 1122002011220020, 65 | 1022102210221110, 66 | 1020112011111020, 67 | 1022102011111000, 68 | 1020112011111020, 69 | 1022121010221210, 70 | 1000201000102220, 71 | 1000201010101111, 72 | 1000202000002220, 73 | 3000202000002220, 74 | 5, 75 | 000000000000000000000000000000000008000000000000, 76 | 77 | #GOGOEND 78 | 1112121211121212, 79 | 1121121211211212, 80 | 1112111211121112, 81 | 1122112212121212, 82 | 1212111212121112, 83 | 1212112112121121, 84 | 2211221122112221, 85 | 1112111212121222, 86 | 1221221022121210, 87 | 3, 88 | 89 | 90 | #END 91 | 92 | 93 | #START P2 94 | 95 | 96 | 10000201, 97 | 10100220, 98 | 1000002220002010, 99 | 1000100000111020, 100 | 10000201, 101 | 10100220, 102 | 1000222000200020, 103 | #MEASURE 2/4 104 | 1010, 105 | #MEASURE 4/4 106 | 300000000000000111200000, 107 | 1112121211121222, 108 | 1112121211211212, 109 | 1112111212211212, 110 | 1112111212103000, 111 | 1212111212121112, 112 | 1112121211211212, 113 | 1112111212221222, 114 | 1112111212121110, 115 | 3003003000303030, 116 | #MEASURE 2/4 117 | , 118 | #MEASURE 4/4 119 | 1010102210101022, 120 | 1010102210201220, 121 | 1010102210101022, 122 | 1010102210112220, 123 | 1010102210101022, 124 | 1010102210202220, 125 | 1010102210101022, 126 | 1000000010212121, 127 | 20011020, 128 | 1000001110100010, 129 | 10011020, 130 | 1000001110001020, 131 | 1011202010102010, 132 | 1011201020101020, 133 | 1011201010112000, 134 | 1112111212121000, 135 | 3000000030000022, 136 | 137 | #GOGOSTART 138 | 1022102010100010, 139 | 1110102011201000, 140 | 1022102010102210, 141 | 1020101011103000, 142 | 3011201020112010, 143 | 1011201020112010, 144 | 1000112210001122, 145 | 1000111011102020, 146 | 1022102010100010, 147 | 1110102011201020, 148 | 1022102011102020, 149 | 1122102011221020, 150 | 1000102210201110, 151 | 1020102210201110, 152 | 3000202000002220, 153 | 3000202000002220, 154 | 5, 155 | 000000000000000000000000000000000008000000000000, 156 | 157 | #GOGOEND 158 | 1212111212121112, 159 | 1212112112121121, 160 | 2211221122112221, 161 | 1112111212121212, 162 | 1112121211121212, 163 | 1121121211211212, 164 | 1112111211121112, 165 | 1122112212121222, 166 | 1221221022121210, 167 | 3, 168 | 169 | 170 | #END 171 | 172 | 173 | COURSE:Oni 174 | LEVEL:10 175 | 176 | STYLE:Double 177 | BALLOON:12 178 | SCOREINIT:430 179 | SCOREDIFF:112 180 | 181 | 182 | #START P1 183 | 184 | 185 | 10000201, 186 | 10100220, 187 | 1000002220002010, 188 | 1000100000111020, 189 | 10000201, 190 | 10100220, 191 | 1000222000200020, 192 | #MEASURE 2/4 193 | 1010, 194 | #MEASURE 4/4 195 | 300000000000000111200000, 196 | 1112121211121222, 197 | 1112121211211212, 198 | 1112111212211212, 199 | 1112111212121000, 200 | 1112121211121222, 201 | 1212111212121112, 202 | 1112111212221222, 203 | 1112111212121110, 204 | 3003003000303030, 205 | #MEASURE 2/4 206 | , 207 | #MEASURE 4/4 208 | 1010221010102210, 209 | 1010221020111020, 210 | 1010221010102210, 211 | 1010221010222220, 212 | 1010221010102210, 213 | 1010221020111020, 214 | 1010221010102210, 215 | 1000000010212121, 216 | 20011020, 217 | 1000001110100010, 218 | 10011020, 219 | 1000001110201000, 220 | 1020102210201011, 221 | 1020102210201011, 222 | 1020102210201011, 223 | 1022102121212111, 224 | 1000000030000022, 225 | 226 | #GOGOSTART 227 | 1010001010221020, 228 | 1022101110102000, 229 | 1110201010221020, 230 | 1000700000000800, 231 | 1020112010222000, 232 | 1020112010222000, 233 | 1122002011220020, 234 | 1022102210221110, 235 | 1020112011111020, 236 | 1022102011111000, 237 | 1020112011111020, 238 | 1022121010221210, 239 | 1000201000102220, 240 | 1000201010101111, 241 | 1000202000002220, 242 | 3000202000002220, 243 | 5, 244 | 000000000000000000000000000000000008000000000000, 245 | 246 | #GOGOEND 247 | 1112121211121212, 248 | 1121121211211212, 249 | 1112111211121112, 250 | 1122112212121212, 251 | 1212111212121112, 252 | 1212112112121121, 253 | 2211221122112221, 254 | 1112111212121222, 255 | 1221221022121210, 256 | 3, 257 | 258 | 259 | #END 260 | 261 | 262 | #START P2 263 | 264 | 265 | 10000201, 266 | 10100220, 267 | 1000002220002010, 268 | 1000100000111020, 269 | 10000201, 270 | 10100220, 271 | 1000222000200020, 272 | #MEASURE 2/4 273 | 1010, 274 | #MEASURE 4/4 275 | 300000000000000111200000, 276 | 1112121211121222, 277 | 1112121211211212, 278 | 1112111212211212, 279 | 1112111212103000, 280 | 1212111212121112, 281 | 1112121211211212, 282 | 1112111212221222, 283 | 1112111212121110, 284 | 3003003000303030, 285 | #MEASURE 2/4 286 | , 287 | #MEASURE 4/4 288 | 1010102210101022, 289 | 1010102210201220, 290 | 1010102210101022, 291 | 1010102210112220, 292 | 1010102210101022, 293 | 1010102210202220, 294 | 1010102210101022, 295 | 1000000010212121, 296 | 20011020, 297 | 1000001110100010, 298 | 10011020, 299 | 1000001110001020, 300 | 1011202010102010, 301 | 1011201020101020, 302 | 1011201010112000, 303 | 1112111212121000, 304 | 3000000030000022, 305 | 306 | #GOGOSTART 307 | 1022102010100010, 308 | 1110102011201000, 309 | 1022102010102210, 310 | 1020101011103000, 311 | 3011201020112010, 312 | 1011201020112010, 313 | 1000112210001122, 314 | 1000111011102020, 315 | 1022102010100010, 316 | 1110102011201020, 317 | 1022102011102020, 318 | 1122102011221020, 319 | 1000102210201110, 320 | 1020102210201110, 321 | 3000202000002220, 322 | 3000202000002220, 323 | 5, 324 | 000000000000000000000000000000000008000000000000, 325 | 326 | #GOGOEND 327 | 1212111212121112, 328 | 1212112112121121, 329 | 2211221122112221, 330 | 1112111212121212, 331 | 1112121211121212, 332 | 1121121211211212, 333 | 1112111211121112, 334 | 1122112212121222, 335 | 1221221022121210, 336 | 3, 337 | 338 | 339 | #END 340 | 341 | 342 | STYLE:Single 343 | BALLOON: 344 | SCOREINIT:590 345 | SCOREDIFF:157 346 | 347 | 348 | #START 349 | 350 | 351 | 10000201, 352 | 10100220, 353 | 1000002220002010, 354 | 1000100000111020, 355 | 10000201, 356 | 10100220, 357 | 1000222000200020, 358 | #MEASURE 2/4 359 | 1010, 360 | #MEASURE 4/4 361 | 300000000000000111200000, 362 | 1112121211121222, 363 | 1112121211211212, 364 | 1112111212211212, 365 | 1112111212121000, 366 | 1112121211121222, 367 | 1112121211121212, 368 | 1112111212221222, 369 | 1112111212121110, 370 | 3003003000303030, 371 | #MEASURE 2/4 372 | , 373 | #MEASURE 4/4 374 | 1010221010102210, 375 | 1010221020111020, 376 | 1010221010102210, 377 | 1010221010221120, 378 | 1010221010102210, 379 | 1010221020111020, 380 | 1010221010102211, 381 | 1000000010212121, 382 | 20011020, 383 | 1000001110200020, 384 | 10011020, 385 | 1000001110222020, 386 | 1020102210201011, 387 | 1020102210201011, 388 | 1020102210201011, 389 | 1022102121212111, 390 | 1000000030000022, 391 | 392 | #GOGOSTART 393 | 1022102010112010, 394 | 1110102011201020, 395 | 1022101020102210, 396 | 1020101011103000, 397 | 3011201020112010, 398 | 1011201020112010, 399 | 1000112210001122, 400 | 1020112011122020, 401 | 1022102010112010, 402 | 1110102011201020, 403 | 1022102011102020, 404 | 1122102011221020, 405 | 1020102210201110, 406 | 1020102210221110, 407 | 3000202000002220, 408 | 3000202000002220, 409 | 5, 410 | 000000000000000000000000000000000008000000000000, 411 | 412 | #GOGOEND 413 | 414 | 1112121211121212, 415 | 1121121211211212, 416 | 1112111211121112, 417 | 1122112212121212, 418 | 1112121211121212, 419 | 1112112112121121, 420 | 2211221122112212, 421 | 1112111212121222, 422 | 1221221022121210, 423 | 3, 424 | 425 | 426 | #END 427 | 428 | 429 | COURSE:Hard 430 | LEVEL:8 431 | BALLOON:8 432 | SCOREINIT:610 433 | SCOREDIFF:165 434 | 435 | #START 436 | 30000201, 437 | 10100220, 438 | 10022021, 439 | 10100111, 440 | 10011201, 441 | 10100220, 442 | 10220202, 443 | #MEASURE 2/4 444 | 10, 445 | #MEASURE 4/4 446 | 3004, 447 | 1110111011011020, 448 | 1110111011101000, 449 | 1110111022202220, 450 | 1110111011103000, 451 | 1110111011011020, 452 | 1110111011101000, 453 | 1110111022202220, 454 | 1101101011101000, 455 | 3003003000303030, 456 | #MEASURE 2/4 457 | , 458 | #MEASURE 4/4 459 | 1010201000111010, 460 | 1010201000111000, 461 | 1010201000111010, 462 | 1010201000222000, 463 | 1010201000111010, 464 | 1010201000111010, 465 | 11211121, 466 | 1000000011111000, 467 | 10011020, 468 | 1000001110000000, 469 | 10011020, 470 | 1000001110002000, 471 | 12121110, 472 | 12121010, 473 | 12101210, 474 | 500000000000000000000000000000000000000000000008, 475 | 03, 476 | 477 | #GOGOSTART 478 | 1022202010111000, 479 | 1110202011102000, 480 | 1022202010111000, 481 | 1000700000000800, 482 | 3011101000200020, 483 | 1011101000222000, 484 | 1110200011102000, 485 | 1110111011102000, 486 | 1022202010111010, 487 | 1110202011102000, 488 | 1022202011101000, 489 | 3333, 490 | 3022202011101000, 491 | 1110202011102000, 492 | 30200220, 493 | 30200220, 494 | 5, 495 | 000000000000000000000000000000000008000000000000, 496 | 497 | #GOGOEND 498 | 1110111011011020, 499 | 1110111011101000, 500 | 1110111022202220, 501 | 1110111011103000, 502 | 1110111011011020, 503 | 1110111011111000, 504 | 1110111022202220, 505 | 1101101101102000, 506 | 3003003000303030, 507 | 3, 508 | , 509 | , 510 | , 511 | , 512 | , 513 | , 514 | #END 515 | 516 | COURSE:Normal 517 | LEVEL:5 518 | BALLOON:8 519 | SCOREINIT:710 520 | SCOREDIFF:217 521 | 522 | #START 523 | 11, 524 | 10100220, 525 | 11, 526 | 10100220, 527 | 11, 528 | 10100220, 529 | 11, 530 | #MEASURE 2/4 531 | 11, 532 | #MEASURE 4/4 533 | 3004, 534 | 11101110, 535 | 11101010, 536 | 11101110, 537 | 11111030, 538 | 11101110, 539 | 22202020, 540 | 11101110, 541 | 11111000, 542 | 3003003000303030, 543 | #MEASURE 2/4 544 | , 545 | #MEASURE 4/4 546 | 11010110, 547 | 1011, 548 | 11010110, 549 | 12, 550 | 11010110, 551 | 1011, 552 | 11010110, 553 | 3, 554 | 10011000, 555 | 22, 556 | 10011000, 557 | 22, 558 | 10111010, 559 | 10111000, 560 | 10111010, 561 | 500000000000000000000000000000000000000000000008, 562 | 03, 563 | 564 | #GOGOSTART 565 | 10222020, 566 | 1222, 567 | 10222020, 568 | 7000000000000800, 569 | 10100220, 570 | 10100220, 571 | 11, 572 | 1111, 573 | 10222020, 574 | 1222, 575 | 10222020, 576 | 3333, 577 | 30100220, 578 | 10100220, 579 | 30000220, 580 | 30000220, 581 | 5, 582 | 000000000000000000000000000000000008000000000000, 583 | 584 | #GOGOEND 585 | 11101110, 586 | 11101010, 587 | 11101110, 588 | 11111030, 589 | 11101110, 590 | 22202020, 591 | 11101110, 592 | 11111030, 593 | 3003003000303030, 594 | 3, 595 | , 596 | , 597 | , 598 | , 599 | , 600 | , 601 | #END 602 | 603 | COURSE:Easy 604 | LEVEL:4 605 | BALLOON: 606 | SCOREINIT:700 607 | SCOREDIFF:280 608 | 609 | #START 610 | 11, 611 | 1110, 612 | 11, 613 | 1, 614 | 11, 615 | 1110, 616 | 11, 617 | #MEASURE 2/4 618 | 1, 619 | #MEASURE 4/4 620 | 30, 621 | 1110, 622 | 11, 623 | 1110, 624 | 11, 625 | 2220, 626 | 22, 627 | 2220, 628 | 22, 629 | 3033, 630 | #MEASURE 2/4 631 | , 632 | #MEASURE 4/4 633 | 1101, 634 | 12, 635 | 1101, 636 | 12, 637 | 1101, 638 | 12, 639 | 1101, 640 | 1, 641 | 11, 642 | 22, 643 | 11, 644 | 22, 645 | 1011, 646 | 1011, 647 | 11, 648 | 500000000000000000000000000000000000000000000008, 649 | 03, 650 | 651 | #GOGOSTART 652 | 1202, 653 | 1202, 654 | 1202, 655 | 500000000000000000000008000000000000000000000000, 656 | 1120, 657 | 1120, 658 | 11, 659 | 1120, 660 | 1202, 661 | 1202, 662 | 1202, 663 | 3330, 664 | 1120, 665 | 1120, 666 | 34, 667 | 34, 668 | 5, 669 | 000000000000000000000000000000000008000000000000, 670 | 671 | #GOGOEND 672 | 1111, 673 | 11, 674 | 1111, 675 | 11, 676 | 2222, 677 | 22, 678 | 2222, 679 | 22, 680 | 3330, 681 | 3, 682 | , 683 | , 684 | , 685 | , 686 | , 687 | , 688 | #END -------------------------------------------------------------------------------- /testing/test_conversion.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | import zipfile 4 | import re 5 | import glob 6 | 7 | import pytest 8 | 9 | from conftest import convert 10 | from tja2fumen.parsers import parse_fumen 11 | 12 | 13 | @pytest.mark.parametrize('id_song', [ 14 | pytest.param('emma'), 15 | pytest.param('butou5'), 16 | pytest.param('shoto9', 17 | marks=pytest.mark.skip("TJA measures do not match fumen.")), 18 | pytest.param('genpe'), 19 | pytest.param('gimcho'), 20 | pytest.param('imcanz'), 21 | pytest.param('clsca'), 22 | pytest.param('linda'), 23 | pytest.param('senpac'), 24 | pytest.param('hol6po'), 25 | pytest.param('mikdp'), 26 | pytest.param('ia6cho'), 27 | ]) 28 | def test_converted_tja_vs_cached_fumen(id_song, tmp_path, entry_point): 29 | # Define the testing directory 30 | path_test = os.path.dirname(os.path.realpath(__file__)) 31 | 32 | # Define the working directory 33 | path_temp = os.path.join(tmp_path, id_song) 34 | os.mkdir(path_temp) 35 | 36 | # Copy input TJA to working directory 37 | path_tja = os.path.join(path_test, "data", f"{id_song}.tja") 38 | path_tja_tmp = os.path.join(path_temp, f"{id_song}.tja") 39 | shutil.copy(path_tja, path_tja_tmp) 40 | 41 | # Convert TJA file to fumen files 42 | convert(path_test, path_tja_tmp, entry_point) 43 | 44 | # Fetch output fumen paths 45 | paths_out = glob.glob(os.path.join(path_temp, "*.bin")) 46 | assert paths_out, f"No bin files generated in {path_temp}" 47 | order = "xmhne" # Ura Oni -> Oni -> Hard -> Normal -> Easy 48 | paths_out = sorted(paths_out, key=lambda s: [order.index(c) if c in order 49 | else len(order) for c in s]) 50 | 51 | # Extract cached fumen files to working directory 52 | path_binzip = os.path.join(path_test, "data", f"{id_song}.zip") 53 | path_bin = os.path.join(path_temp, "ca_bins") 54 | with zipfile.ZipFile(path_binzip, 'r') as zip_ref: 55 | zip_ref.extractall(path_bin) 56 | 57 | # Compare cached fumen with generated fumen 58 | for path_out in paths_out: 59 | # Difficulty introspection to help with debugging 60 | i_difficult_id = os.path.basename(path_out).split(".")[0].split("_")[1] 61 | # 0. Read fumen data (converted vs. cached) 62 | path_out_fumen = os.path.join(path_bin, os.path.basename(path_out)) 63 | co_song = parse_fumen(path_out, exclude_empty_measures=True) 64 | ca_song = parse_fumen(path_out_fumen, exclude_empty_measures=True) 65 | # 1. Check song headers 66 | checkValidHeader(co_song.header) 67 | checkValidHeader(ca_song.header) 68 | for header_property in ['order', 69 | 'b432_b435_has_branches', 70 | 'b436_b439_hp_max', 71 | 'b440_b443_hp_clear', 72 | 'b444_b447_hp_gain_good', 73 | 'b448_b451_hp_gain_ok', 74 | 'b452_b455_hp_loss_bad', 75 | 'b456_b459_normal_normal_ratio', 76 | 'b460_b463_normal_professional_ratio', 77 | 'b464_b467_normal_master_ratio']: 78 | check(co_song.header, ca_song.header, header_property, abv=1) 79 | # NB: KAGEKIYO's branching condition is very unique (BIG only), which 80 | # cannot be expressed in a TJA file. So, we skip checking the 81 | # `branch_point` header values for KAGEKIYO. 82 | if id_song != 'genpe': 83 | for header_property in ['b000_b431_timing_windows', 84 | 'b468_b471_branch_pts_good', 85 | 'b472_b475_branch_pts_ok', 86 | 'b476_b479_branch_pts_bad', 87 | 'b480_b483_branch_pts_drumroll', 88 | 'b484_b487_branch_pts_good_big', 89 | 'b488_b491_branch_pts_ok_big', 90 | 'b492_b495_branch_pts_drumroll_big', 91 | 'b496_b499_branch_pts_balloon', 92 | 'b500_b503_branch_pts_kusudama']: 93 | check(co_song.header, ca_song.header, header_property) 94 | # 2. Check song metadata 95 | check(co_song, ca_song, 'score_init') 96 | check(co_song, ca_song, 'score_diff') 97 | # 3. Check measure data 98 | for i_measure in range(max([len(co_song.measures), 99 | len(ca_song.measures)])): 100 | # NB: We could assert that len(measures) is the same for both 101 | # songs, then iterate through zipped measures. But, if there is a 102 | # mismatched number of measures, we want to know _where_ it 103 | # occurs. So, we let the comparison go on using the max length of 104 | # both songs until something else fails. 105 | co_measure = co_song.measures[i_measure] 106 | ca_measure = ca_song.measures[i_measure] 107 | # 3a. Check measure metadata 108 | check(co_measure, ca_measure, 'bpm', i_measure, abv=0.01) 109 | check(co_measure, ca_measure, 'offset_start', i_measure, abv=0.15) 110 | check(co_measure, ca_measure, 'gogo', i_measure) 111 | check(co_measure, ca_measure, 'barline', i_measure) 112 | 113 | # NB: KAGEKIYO's fumen has some strange details that can't be 114 | # replicated using the TJA charting format. So, for now, we use a 115 | # special case to skip checking: 116 | # A) notes for certain measures and 117 | # B) branchInfo 118 | if id_song == 'genpe': 119 | # A) The 2/4 measures in the Ura of KAGEKIYO's official Ura 120 | # fumen don't match the wikiwiki.jp/TJA charts. In the official 121 | # fumen, the note ms offsets of branches 5/12/17/etc. go _past_ 122 | # the duration of the measure. This behavior is impossible to 123 | # represent using the TJA format, so we skip checking notes 124 | # for these measures, since the rest of the measures have 125 | # perfect note ms offsets anyway. 126 | if (i_difficult_id == "x" and 127 | i_measure in [5, 6, 12, 13, 17, 18, 26, 27, 128 | 46, 47, 51, 52, 56, 57]): 129 | continue 130 | # B) The branching condition for KAGEKIYO is very strange 131 | # (accuracy for the 7 big notes in the song) So, we only test 132 | # the branchInfo bytes for non-KAGEKIYO songs: 133 | else: 134 | check(co_measure, ca_measure, 'branch_info', i_measure) 135 | 136 | # 3b. Check measure notes 137 | for i_branch in ['normal', 'professional', 'master']: 138 | co_branch = co_measure.branches[i_branch] 139 | ca_branch = ca_measure.branches[i_branch] 140 | # NB: We only check speed for non-empty branches, as fumens 141 | # store speed changes even for empty branches. 142 | if co_branch.length != 0: 143 | check(co_branch, ca_branch, 'speed', i_measure, i_branch) 144 | # NB: We could assert that len(notes) is the same for both 145 | # songs, then iterate through zipped notes. But, if there is a 146 | # mismatched number of notes, we want to know _where_ it 147 | # occurs. So, we let the comparison go on using the max length 148 | # of both branches until something else fails. 149 | for i_note in range(max([co_branch.length, ca_branch.length])): 150 | co_note = co_branch.notes[i_note] 151 | ca_note = ca_branch.notes[i_note] 152 | check(co_note, ca_note, 'note_type', i_measure, 153 | i_branch, i_note, func=normalize_type) 154 | check(co_note, ca_note, 'pos', i_measure, 155 | i_branch, i_note, abv=0.1) 156 | # NB: Drumroll duration doesn't always end exactly on a 157 | # beat. Plus, TJA charters often eyeball drumrolls, 158 | # leading them to be often off by a 1/4th/8th/16th/etc. 159 | # These charting errors are fixable, but tedious to do 160 | # when writing tests. So, I've added a try/except so that 161 | # they can be checked locally with a breakpoint when 162 | # adding new songs, but so that fixing every 163 | # duration-related chart error isn't 100% mandatory. 164 | try: 165 | check(co_note, ca_note, 'duration', i_measure, 166 | i_branch, i_note, abv=25.0) 167 | except AssertionError: 168 | pass 169 | if ca_note.note_type in ["Balloon", "Kusudama"]: 170 | check(co_note, ca_note, 'hits', i_measure, 171 | i_branch, i_note) 172 | else: 173 | check(co_note, ca_note, 'score_init', i_measure, 174 | i_branch, i_note) 175 | check(co_note, ca_note, 'score_diff', i_measure, 176 | i_branch, i_note) 177 | # NB: 'item' still needs to be implemented: 178 | # https://github.com/vivaria/tja2fumen/issues/17 179 | # check(co_note, ca_note, 'item', i_measure, 180 | # i_branch, i_note) 181 | 182 | 183 | def check(converted_obj, cached_obj, prop, measure=None, 184 | branch=None, note=None, func=None, abv=None): 185 | # NB: TJA parser/converter uses 0-based indexing, but TJA files use 186 | # 1-based indexing. So, we increment 1 in the error message to more easily 187 | # identify problematic lines in TJA files. 188 | msg_failure = f"'{prop}' mismatch" 189 | msg_failure += f": measure '{measure+1}'" if measure is not None else "" 190 | msg_failure += f", branch '{branch}'" if branch is not None else "" 191 | msg_failure += f", note '{note+1}'" if note is not None else "" 192 | converted_val = converted_obj.__getattribute__(prop) 193 | cached_val = cached_obj.__getattribute__(prop) 194 | if func: 195 | assert func(converted_val) == func(cached_val), msg_failure 196 | elif abv: 197 | assert converted_val == pytest.approx(cached_val, abs=abv), msg_failure 198 | else: 199 | assert converted_val == cached_val, msg_failure 200 | 201 | 202 | def normalize_type(note_type): 203 | return re.sub(r'[0-9]', '', note_type) 204 | 205 | 206 | def checkValidHeader(header): 207 | assert len(header.raw_bytes) == 520 208 | assert header.b432_b435_has_branches in [0, 1] 209 | assert header.b436_b439_hp_max == 10000 210 | assert header.b440_b443_hp_clear in [6000, 7000, 8000] 211 | assert 10 <= header.b444_b447_hp_gain_good <= 1020 212 | assert 5 <= header.b448_b451_hp_gain_ok <= 1020 213 | assert -765 <= header.b452_b455_hp_loss_bad <= -20 214 | assert header.b456_b459_normal_normal_ratio <= 65536 215 | assert header.b460_b463_normal_professional_ratio <= 65536 216 | assert header.b464_b467_normal_master_ratio <= 65536 217 | assert header.b468_b471_branch_pts_good in [20, 0, 1, 2] 218 | assert header.b472_b475_branch_pts_ok in [10, 0, 1] 219 | assert header.b476_b479_branch_pts_bad == 0 220 | assert header.b480_b483_branch_pts_drumroll in [1, 0] 221 | assert header.b484_b487_branch_pts_good_big in [20, 0, 1, 2] 222 | assert header.b488_b491_branch_pts_ok_big in [10, 0, 1] 223 | assert header.b492_b495_branch_pts_drumroll_big in [1, 0] 224 | assert header.b496_b499_branch_pts_balloon in [30, 0, 1] 225 | assert header.b500_b503_branch_pts_kusudama in [30, 0] 226 | -------------------------------------------------------------------------------- /testing/data/gimcho.tja: -------------------------------------------------------------------------------- 1 | BPM:220.000214 2 | OFFSET:-8.827 3 | 4 | COURSE:Edit 5 | LEVEL:10 6 | BALLOON: 7 | SCOREINIT:290 8 | SCOREDIFF:70 9 | 10 | 11 | #START 12 | 13 | 14 | 1000201020111020, 15 | 0010201021101020, 16 | 0010201020111020, 17 | 0010201020111000, 18 | 4000201020111020, 19 | 0010201021101020, 20 | 0010201020111020, 21 | 0010201020111000, 22 | 2222101020111020, 23 | 01212444, 24 | 2211201020101020, 25 | 0010201020112220, 26 | 2222101020111020, 27 | 01212444, 28 | 2211201020101020, 29 | 0010201020112220, 30 | 2222101020111020, 31 | 01212444, 32 | 2211201020111020, 33 | 0010201020112220, 34 | 2222101020111020, 35 | 01212444, 36 | 2211201020111020, 37 | 01203333, 38 | 1110211011201020, 39 | 1110211011201020, 40 | 1110211011201020, 41 | 1110211011201000, 42 | 1110211011201020, 43 | 1110211011201020, 44 | 1110211011201020, 45 | 1110200020201110, 46 | 2020222020002020, 47 | 0022202030004000, 48 | 1010111010001010, 49 | 0011101030004000, 50 | 34003400, 51 | 34003400, 52 | 43434343, 53 | 34343400, 54 | 55 | #GOGOSTART 56 | 1000201011102010, 57 | 0010201011102010, 58 | 0010201011102010, 59 | 0010201011102010, 60 | 1010201021101020, 61 | 0010201021101020, 62 | 0010201021101020, 63 | 0010201021102020, 64 | 1010201022112010, 65 | 0010201022112010, 66 | 0010201022112010, 67 | 0010201022112010, 68 | 1010201012221020, 69 | 0010201012221020, 70 | 0010201012221040, 71 | 04043030, 72 | 73 | #GOGOEND 74 | 2010201020221020, 75 | 0010201020221020, 76 | 0010201020221020, 77 | 00204444, 78 | 0000201110111020, 79 | 0000201110111020, 80 | 0000201110111020, 81 | 00203043, 82 | 2222101020111020, 83 | 01212444, 84 | 2211201020111020, 85 | 0010201020112220, 86 | 2222101022111020, 87 | 0010211010404040, 88 | 2211201021111020, 89 | 0010201020112220, 90 | 2222101022111020, 91 | 0010211010404040, 92 | 2211201021112020, 93 | 0010201020112220, 94 | 2222101021111020, 95 | 0020211010404040, 96 | 2211201021112020, 97 | 0020201022101010, 98 | 99 | #GOGOSTART 100 | 2221112221112221, 101 | 1122211122211122, 102 | 2111111112221111, 103 | 1222, 104 | 1111222211222211, 105 | 2222122212221110, 106 | 2211222211112222, 107 | 1111222211112222, 108 | 2210200000002210, 109 | 20022202, 110 | 2211221122112211, 111 | 2000200020002011, 112 | 1122101122102210, 113 | 2222102222102210, 114 | 1111222210002022, 115 | 20003300, 116 | 117 | #GOGOEND 118 | 2011101020111020, 119 | 0022202030004000, 120 | 1022202010001010, 121 | 0011101030004000, 122 | 34003400, 123 | 34003400, 124 | 43434343, 125 | 34343400, 126 | 127 | #GOGOSTART 128 | 1000201011102010, 129 | 0010201011102010, 130 | 0010201011102010, 131 | 0010201011102010, 132 | 1010201021101020, 133 | 0010201021101020, 134 | 0010201021101020, 135 | 0010201021102020, 136 | 1010201022112010, 137 | 0010201022112010, 138 | 0010201022112010, 139 | 0010201022112010, 140 | 1010201012221020, 141 | 0010201012221020, 142 | 0010201012221040, 143 | 04043020, 144 | 145 | #GOGOEND 146 | 2010201022102010, 147 | 2010201022102010, 148 | 2010201022102010, 149 | 00204444, 150 | 1000201022102010, 151 | 2010201022102010, 152 | 2010201022102010, 153 | 20203334, 154 | 155 | 156 | #END 157 | 158 | 159 | COURSE:Oni 160 | LEVEL:8 161 | BALLOON: 162 | SCOREINIT:330 163 | SCOREDIFF:82 164 | 165 | 166 | #START 167 | 168 | 169 | 1000200010111020, 170 | 0010200010111020, 171 | 0010200010111020, 172 | 0010200010111000, 173 | 1000200010111020, 174 | 0010200010111020, 175 | 0010200010111020, 176 | 0010200010111000, 177 | 2220100022201020, 178 | 01201444, 179 | 2220200011101010, 180 | 0010200011101000, 181 | 2220100022201020, 182 | 01201444, 183 | 2220200011101010, 184 | 0010200011101000, 185 | 2220100022201020, 186 | 01201444, 187 | 2220200011101010, 188 | 0010200011101000, 189 | 2220100022201020, 190 | 01201444, 191 | 2220200022201010, 192 | 01203030, 193 | 1110200010201020, 194 | 1110200010201020, 195 | 1110200010201020, 196 | 1110200010201000, 197 | 1110200010201020, 198 | 1110200010201020, 199 | 1110200010201020, 200 | 3344, 201 | 11221012, 202 | 02223040, 203 | 22112021, 204 | 01113040, 205 | 34003400, 206 | 34003400, 207 | 44444444, 208 | 33333300, 209 | 210 | #GOGOSTART 211 | 10201121, 212 | 01201121, 213 | 01201121, 214 | 01201120, 215 | 10201121, 216 | 01201121, 217 | 01201121, 218 | 01201120, 219 | 1000201011102010, 220 | 0010201011102010, 221 | 0010201011102010, 222 | 0010201011102000, 223 | 1000201011102010, 224 | 0010201011102010, 225 | 0010201011102040, 226 | 04043030, 227 | 228 | #GOGOEND 229 | 11020202, 230 | 01020202, 231 | 01020202, 232 | 00201111, 233 | 00010102, 234 | 00010102, 235 | 00010102, 236 | 00201011, 237 | 2220100022201020, 238 | 01201444, 239 | 2220200011101010, 240 | 0010200011101000, 241 | 2220100022201020, 242 | 01201444, 243 | 2220200011101010, 244 | 0010200011101000, 245 | 2220100022201020, 246 | 01201444, 247 | 2220200011101010, 248 | 0010200011101000, 249 | 2220100022201020, 250 | 01201444, 251 | 2220200022201010, 252 | 01203030, 253 | 254 | #GOGOSTART 255 | 1110101011101010, 256 | 1110101011101010, 257 | 1110111011101110, 258 | 1222, 259 | 1110111011101000, 260 | 2220222022202000, 261 | 1110222011102220, 262 | 1110222011102000, 263 | 2220200020002220, 264 | 20202202, 265 | 2220111022201110, 266 | 2222, 267 | 1111101111101000, 268 | 2222202222202000, 269 | 1110222011102022, 270 | 20003300, 271 | 272 | #GOGOEND 273 | 11221112, 274 | 02223040, 275 | 22112021, 276 | 01113040, 277 | 34003400, 278 | 34003400, 279 | 44444444, 280 | 33333300, 281 | 282 | #GOGOSTART 283 | 10201121, 284 | 01201121, 285 | 01201121, 286 | 01201122, 287 | 10201121, 288 | 01201121, 289 | 01201121, 290 | 01201122, 291 | 1000201011102010, 292 | 0010201011102010, 293 | 0010201011102010, 294 | 0010201011102020, 295 | 1000201011102010, 296 | 0010201011102010, 297 | 0010201011102030, 298 | 03034000, 299 | 300 | #GOGOEND 301 | 11020202, 302 | 01020202, 303 | 01020202, 304 | 00204444, 305 | 00020202, 306 | 00020202, 307 | 00020202, 308 | 00203334, 309 | 310 | 311 | #END 312 | 313 | 314 | COURSE:Hard 315 | LEVEL:7 316 | BALLOON: 317 | SCOREINIT:340 318 | SCOREDIFF:87 319 | 320 | 321 | #START 322 | 323 | 324 | 10201112, 325 | 01201112, 326 | 01201112, 327 | 01201110, 328 | 10201112, 329 | 01201112, 330 | 01201112, 331 | 01201110, 332 | 20102212, 333 | 01201222, 334 | 20102212, 335 | 01201110, 336 | 20102212, 337 | 01201222, 338 | 20102212, 339 | 01201110, 340 | 20102212, 341 | 01201222, 342 | 20102212, 343 | 01201110, 344 | 20102212, 345 | 01201222, 346 | 20102212, 347 | 01203030, 348 | 11201210, 349 | 11201210, 350 | 11201210, 351 | 11201210, 352 | 11201212, 353 | 11201212, 354 | 11201212, 355 | 3344, 356 | 11111011, 357 | 01113040, 358 | 22222022, 359 | 02223040, 360 | 34003400, 361 | 34003400, 362 | 44444444, 363 | 33333300, 364 | 365 | #GOGOSTART 366 | 10201112, 367 | 02020102, 368 | 02020102, 369 | 02021010, 370 | 10201112, 371 | 02020102, 372 | 02020102, 373 | 02020011, 374 | 10201112, 375 | 02020102, 376 | 02020102, 377 | 02021010, 378 | 10201112, 379 | 02020102, 380 | 02020104, 381 | 04040000, 382 | 383 | #GOGOEND 384 | 11020202, 385 | 01020202, 386 | 01020202, 387 | 00201111, 388 | 00010102, 389 | 00010102, 390 | 00010102, 391 | 00201011, 392 | 20102212, 393 | 01201222, 394 | 20102212, 395 | 01201110, 396 | 20102212, 397 | 01201222, 398 | 20102212, 399 | 01201110, 400 | 20102212, 401 | 01201222, 402 | 20102212, 403 | 01201110, 404 | 20102212, 405 | 01201222, 406 | 20102212, 407 | 01111110, 408 | 409 | #GOGOSTART 410 | 1110100011101000, 411 | 1110100011101000, 412 | 1110111011101110, 413 | 1222, 414 | 1110200011102000, 415 | 1110200011102000, 416 | 1110222011102000, 417 | 1110222011102000, 418 | 2220200020002220, 419 | 20202202, 420 | 1110100011101000, 421 | 1222, 422 | 500000000000000000000000000000000008000000000000, 423 | 500000000000000000000000000000000008000000000000, 424 | 1110222010002022, 425 | 20003300, 426 | 427 | #GOGOEND 428 | 11221112, 429 | 02223040, 430 | 22112021, 431 | 01113040, 432 | 34003400, 433 | 34003400, 434 | 44444444, 435 | 33333300, 436 | 437 | #GOGOSTART 438 | 10201112, 439 | 02020102, 440 | 02020102, 441 | 02021010, 442 | 10201112, 443 | 02020102, 444 | 02020102, 445 | 00201011, 446 | 10201112, 447 | 02020102, 448 | 02020102, 449 | 02021010, 450 | 10201112, 451 | 02020102, 452 | 02020104, 453 | 04043000, 454 | 455 | #GOGOEND 456 | 11020202, 457 | 01020202, 458 | 01020202, 459 | 00203333, 460 | 00010102, 461 | 00010102, 462 | 00010102, 463 | 00204444, 464 | #END 465 | 466 | COURSE:Normal 467 | LEVEL:6 468 | BALLOON:4 469 | SCOREINIT:490 470 | SCOREDIFF:132 471 | 472 | #START 473 | 10001011, 474 | 00101011, 475 | 00101011, 476 | 0110, 477 | 10001011, 478 | 00101011, 479 | 00101011, 480 | 0110, 481 | 10002011, 482 | 0022, 483 | 10001011, 484 | 0210, 485 | 10002011, 486 | 0022, 487 | 10001011, 488 | 0210, 489 | 10002011, 490 | 0022, 491 | 10001011, 492 | 0210, 493 | 10002011, 494 | 0022, 495 | 10001011, 496 | 0233, 497 | 1202, 498 | 1202, 499 | 1202, 500 | 1210, 501 | 1202, 502 | 1202, 503 | 1202, 504 | 3344, 505 | 5, 506 | 000000000008000000000000300000000000400000000000, 507 | 5, 508 | 000000000008000000000000300000000000400000000000, 509 | 43, 510 | 43, 511 | 4444, 512 | 3330, 513 | 514 | #GOGOSTART 515 | 10001003, 516 | 00010003, 517 | 00010003, 518 | 0011, 519 | 20002004, 520 | 00020004, 521 | 00020004, 522 | 0022, 523 | 10001003, 524 | 00010003, 525 | 00010003, 526 | 0011, 527 | 20002004, 528 | 00020004, 529 | 00020004, 530 | 00030000, 531 | 532 | #GOGOEND 533 | 10020202, 534 | 00020202, 535 | 00020202, 536 | 00200004, 537 | 00010101, 538 | 00010101, 539 | 00010101, 540 | 0110, 541 | 10002011, 542 | 0022, 543 | 10001011, 544 | 0210, 545 | 10002011, 546 | 0022, 547 | 10001011, 548 | 0210, 549 | 10002011, 550 | 0022, 551 | 10001011, 552 | 0210, 553 | 10002011, 554 | 0022, 555 | 10001011, 556 | 0708, 557 | 558 | #GOGOSTART 559 | 1111, 560 | 1111, 561 | 5, 562 | 000000000000000000000000000008000000000000000000, 563 | 1122, 564 | 1122, 565 | 1110, 566 | 2220, 567 | 4404, 568 | 4, 569 | 1111, 570 | 1, 571 | 10010010, 572 | 20020020, 573 | 1111, 574 | 13, 575 | 576 | #GOGOEND 577 | 5, 578 | 000000000008000000000000300000000000400000000000, 579 | 5, 580 | 000000000008000000000000300000000000400000000000, 581 | 43, 582 | 43, 583 | 4444, 584 | 3330, 585 | 586 | #GOGOSTART 587 | 10001003, 588 | 00010003, 589 | 00010003, 590 | 0011, 591 | 20002004, 592 | 00020004, 593 | 00020004, 594 | 0022, 595 | 10001003, 596 | 00010003, 597 | 00010003, 598 | 0011, 599 | 20002004, 600 | 00020004, 601 | 00020004, 602 | 00030000, 603 | 604 | #GOGOEND 605 | 10020202, 606 | 00020202, 607 | 00020202, 608 | 00200004, 609 | 00010101, 610 | 00010101, 611 | 00010101, 612 | 00103003, 613 | #END 614 | 615 | COURSE:Easy 616 | LEVEL:4 617 | BALLOON:3 618 | SCOREINIT:450 619 | SCOREDIFF:142 620 | 621 | #START 622 | 11, 623 | 0110, 624 | 0110, 625 | 0110, 626 | 11, 627 | 0110, 628 | 0110, 629 | 0110, 630 | 11, 631 | 0022, 632 | 11, 633 | , 634 | 11, 635 | 0022, 636 | 11, 637 | , 638 | 11, 639 | 0022, 640 | 11, 641 | , 642 | 11, 643 | 0022, 644 | 11, 645 | 03, 646 | 1100, 647 | 1100, 648 | 1100, 649 | 1110, 650 | 1100, 651 | 1100, 652 | 1100, 653 | 3, 654 | 5, 655 | 000008000000000000000000400000000000000000000000, 656 | 5, 657 | 000008000000000000000000300000000000000000000000, 658 | 43, 659 | 43, 660 | 6, 661 | 000000000000000000000008000000000000000000000000, 662 | 663 | #GOGOSTART 664 | 10001003, 665 | 00000003, 666 | 00000003, 667 | , 668 | 20002004, 669 | 00000004, 670 | 00000004, 671 | , 672 | 10001003, 673 | 00000003, 674 | 00000003, 675 | , 676 | 20002004, 677 | 00000004, 678 | 00000004, 679 | 00040000, 680 | 681 | #GOGOEND 682 | 00020202, 683 | 00020202, 684 | 00020202, 685 | , 686 | 00010101, 687 | 00010101, 688 | 00010101, 689 | , 690 | 11, 691 | 0022, 692 | 11, 693 | , 694 | 11, 695 | 0022, 696 | 11, 697 | , 698 | 11, 699 | 0022, 700 | 11, 701 | , 702 | 11, 703 | 0022, 704 | 11, 705 | 0708, 706 | 707 | #GOGOSTART 708 | 11, 709 | 11, 710 | 5, 711 | 000000000000000000000000000008000000000000000000, 712 | 12, 713 | 12, 714 | 11, 715 | 22, 716 | 4004, 717 | , 718 | 500000000000000000000000000000000000000000000008, 719 | , 720 | 11, 721 | 22, 722 | 11, 723 | 1, 724 | 725 | #GOGOEND 726 | 5, 727 | 000008000000000000000000400000000000000000000000, 728 | 5, 729 | 000008000000000000000000300000000000000000000000, 730 | 43, 731 | 43, 732 | 4444, 733 | 3330, 734 | 735 | #GOGOSTART 736 | 10001003, 737 | 00000003, 738 | 00000003, 739 | , 740 | 20002004, 741 | 00000004, 742 | 00000004, 743 | , 744 | 10001003, 745 | 00000003, 746 | 00000003, 747 | , 748 | 20002004, 749 | 00000004, 750 | 00000003, 751 | 03, 752 | 753 | #GOGOEND 754 | 00040000, 755 | 00040000, 756 | 00040000, 757 | , 758 | 00030000, 759 | 00030000, 760 | 00030000, 761 | 00003003, 762 | , 763 | , 764 | #END -------------------------------------------------------------------------------- /testing/data/ia6cho.tja: -------------------------------------------------------------------------------- 1 | // This song features mid-measure BPMCHANGE commands. 2 | // It also mixes in SCROLL and MEASURE commands next to the BPMCHANGE commands. 3 | BPM:185.9998 4 | OFFSET:-11.4302 5 | 6 | COURSE:Edit 7 | LEVEL:9 8 | BALLOON: 9 | SCOREINIT:400 10 | SCOREDIFF:102 11 | 12 | 13 | #START 14 | 15 | 16 | #BARLINEOFF 17 | , 18 | 19 | #GOGOSTART 20 | #BARLINEON 21 | 33000000, 22 | 33000000, 23 | 33000000, 24 | 500000000000000000000000000000000000000008000000, 25 | 1000200012111020, 26 | 1010200012111020, 27 | 1121101212101222, 28 | 1022122000000000, 29 | 30 | #GOGOEND 31 | 11, 32 | 12, 33 | 11, 34 | 12, 35 | 10022010, 36 | 10022010, 37 | 10101011, 38 | 11111020, 39 | 1020002020200022, 40 | 1020002010202222, 41 | 1020002020200022, 42 | 1020002010202222, 43 | 1020002010002022, 44 | 1020002010002022, 45 | 10210021, 46 | 0040000010102222, 47 | 10010030, 48 | , 49 | 10210030, 50 | 000000211211, 51 | 11, 52 | 1000001120002222, 53 | 11113333, 54 | 3022, 55 | 56 | #GOGOSTART 57 | 1102102011021020, 58 | 1122102012221020, 59 | 1102102011021021, 60 | 1102102012221020, 61 | 1102102011021020, 62 | 1122102012221020, 63 | 1122112211221122, 64 | 11111040, 65 | 1000400011021021, 66 | 1102102012221020, 67 | 1102102011211020, 68 | 3000300012221020, 69 | 1102102011021020, 70 | 1122102012221020, 71 | 1122112211022122, 72 | 1010101020222220, 73 | 74 | #GOGOEND 75 | 1010112011012020, 76 | 1010112011221121, 77 | 10222022, 78 | 1111200022022111, 79 | 1102112011021120, 80 | 1020112211112111, 81 | 1122112212121122, 82 | 100200100200100200100200500000000000000008000000, 83 | 33003300, 84 | 300000000000300000000000600000000008000000000000, 85 | 33003300, 86 | 400000000000400000000000600000000008000000000000, 87 | 10101110, 88 | 100100100100201010201010, 89 | 10012001, 90 | 0010001020001011, 91 | 2000200020112010, 92 | 200000200200202020202020, 93 | , 94 | 3, 95 | , 96 | , 97 | 30333022, 98 | 99 | #GOGOSTART 100 | 1102102011021020, 101 | 1122102012221020, 102 | 1122112211022122, 103 | 11111040, 104 | 1000400011021021, 105 | 1102102012221020, 106 | 1102102011211020, 107 | 3000300012221020, 108 | 1102102011021020, 109 | 1122102012221020, 110 | 1122112211221122, 111 | 11111022, 112 | 11021020 113 | #BPMCHANGE 178 114 | #SCROLL 1.04 115 | 1102 116 | #BPMCHANGE 168 117 | #SCROLL 1.11 118 | 1020, 119 | #MEASURE 5/4 120 | #BPMCHANGE 159 121 | #SCROLL 1 122 | 11 123 | #BPMCHANGE 144 124 | 11 125 | #BPMCHANGE 126 126 | 33 127 | 128 | #GOGOEND 129 | #BPMCHANGE 107 130 | 33 131 | #BPMCHANGE 60.61 132 | 00, 133 | 134 | #GOGOSTART 135 | #MEASURE 2/4 136 | #BPMCHANGE 186 137 | 40112010, 138 | #MEASURE 4/4 139 | 1122112211022122, 140 | 11111040, 141 | 1000200012111020, 142 | 1010200012111020, 143 | 1000200012111020, 144 | 1020121110001010, 145 | 1011202012111020, 146 | 1011202012111120, 147 | 1121101212101222, 148 | 100000200200100200200000500000000000000008000000, 149 | 1121101212101222, 150 | 1022122 151 | 152 | #GOGOEND 153 | 000000000, 154 | 155 | 156 | #END 157 | 158 | 159 | COURSE:Oni 160 | LEVEL:9 161 | BALLOON: 162 | SCOREINIT:370 163 | SCOREDIFF:90 164 | 165 | 166 | #START 167 | 168 | 169 | #BARLINEOFF 170 | 0000000000001122, 171 | 172 | #GOGOSTART 173 | #BARLINEON 174 | 1010201022111020, 175 | 1010201022111020, 176 | 1010201022111020, 177 | 1020221110222222, 178 | 1011201022111020, 179 | 1011201022111020, 180 | 2211102211102211, 181 | 1022111000000000, 182 | 183 | #GOGOEND 184 | 10011001, 185 | 10111011, 186 | 10011011, 187 | 10111000, 188 | 10011001, 189 | 10011010, 190 | 10110111, 191 | 00211020, 192 | 1000201010201120, 193 | 1010201022102011, 194 | 1000201010201120, 195 | 1010201022102022, 196 | 1000201010202011, 197 | 1010201010202011, 198 | 1010201020111020, 199 | 0020111010202222, 200 | 10230230, 201 | 0022, 202 | 30230230, 203 | 000000221111, 204 | 1121, 205 | 1000000020222222, 206 | 10333333, 207 | 3034, 208 | 209 | #GOGOSTART 210 | 3002102010112010, 211 | 1022102010112010, 212 | 1022112011102010, 213 | 1011221010002222, 214 | 1022102010112010, 215 | 1011221010001010, 216 | 2021202120212021, 217 | 2020101020002211, 218 | 2000221120021020, 219 | 1022102010112010, 220 | 1022112011102010, 221 | 3000300030222222, 222 | 1022102010112010, 223 | 1011221010001010, 224 | 2021202120212021, 225 | 2020101020002222, 226 | 227 | #GOGOEND 228 | 1020112010201121, 229 | 1020112011112222, 230 | 1, 231 | 1111200011112222, 232 | 1020102210201122, 233 | 1020112211112222, 234 | 1111221212112212, 235 | 2211221111222210, 236 | 33003300, 237 | 3000300030002211, 238 | 13003300, 239 | 3000300030222222, 240 | 10111111, 241 | 100100100100202010101010, 242 | 10012022, 243 | 1020101020001011, 244 | 2010201120102011, 245 | 100000100100101010101010, 246 | , 247 | 3, 248 | , 249 | 0002, 250 | 30333040, 251 | 252 | #GOGOSTART 253 | 1022102010112010, 254 | 1011221010001010, 255 | 2021202120212021, 256 | 2020101020002211, 257 | 2000221120021020, 258 | 1022102010112010, 259 | 1022112011102010, 260 | 1011221010002222, 261 | 1022102010112010, 262 | 1011221010001010, 263 | 2021202120212021, 264 | 2020101020002222, 265 | 10112010 266 | #BPMCHANGE 178 267 | #SCROLL 1.04 268 | 1011 269 | #BPMCHANGE 168 270 | #SCROLL 1.11 271 | 2020, 272 | #MEASURE 5/4 273 | #BPMCHANGE 159 274 | #SCROLL 1 275 | 11 276 | #BPMCHANGE 144 277 | 21 278 | #BPMCHANGE 126 279 | 33 280 | 281 | #GOGOEND 282 | #BPMCHANGE 107 283 | 33 284 | #BPMCHANGE 60.61 285 | 00, 286 | 287 | #GOGOSTART 288 | #MEASURE 2/4 289 | #BPMCHANGE 186 290 | 20112010, 291 | #MEASURE 4/4 292 | 2021202120212021, 293 | 2020101020001122, 294 | 1010201022111020, 295 | 1010201022111020, 296 | 1010201022111020, 297 | 1020221110001020, 298 | 1011201022111020, 299 | 1011201022111020, 300 | 2211102211102211, 301 | 1022111011112222, 302 | 1122101122101122, 303 | 10112210 304 | #GOGOEND 305 | 00000000, 306 | 307 | 308 | #END 309 | 310 | 311 | COURSE:Hard 312 | LEVEL:7 313 | BALLOON:11 314 | SCOREINIT:450 315 | SCOREDIFF:117 316 | 317 | 318 | #START 319 | 320 | 321 | #BARLINEOFF 322 | , 323 | 324 | #GOGOSTART 325 | #BARLINEON 326 | 33000000, 327 | 33000000, 328 | 33000000, 329 | 1010111010001010, 330 | 1000200011101000, 331 | 1000200011101000, 332 | 1110101110101110, 333 | 1011101000000000, 334 | 335 | #GOGOEND 336 | 10011001, 337 | 1110, 338 | 10011011, 339 | 1110, 340 | 10011001, 341 | 10011010, 342 | 10110011, 343 | 00211020, 344 | 10211021, 345 | 10202021, 346 | 1000201010002011, 347 | 1220, 348 | 10211020, 349 | 1000201010002011, 350 | 10210012, 351 | 0022, 352 | 30230230, 353 | 0022, 354 | 30230230, 355 | 0011, 356 | 2212, 357 | 1044, 358 | 3333, 359 | 3033, 360 | 361 | #GOGOSTART 362 | 4000101020011010, 363 | 1001101010001010, 364 | 10112210, 365 | 10112011, 366 | 20112011, 367 | 11102011, 368 | 1011101110111011, 369 | 11102011, 370 | 2000101020011010, 371 | 1001101010001010, 372 | 10112210, 373 | 30303011, 374 | 20112011, 375 | 11102011, 376 | 1011101110111011, 377 | 11104000, 378 | 379 | #GOGOEND 380 | 2000101020011010, 381 | 11102000, 382 | 1000202020222000, 383 | 10112000, 384 | 10101210, 385 | 11101000, 386 | 6, 387 | 000000000000000000000000000000000008000000000000, 388 | 33003300, 389 | 3330, 390 | 33003300, 391 | 3330, 392 | 10112010, 393 | 11102000, 394 | 12, 395 | 11102000, 396 | 1121, 397 | 100000100000100000000000600000000000000000000008, 398 | , 399 | 3, 400 | , 401 | , 402 | 30333040, 403 | 404 | #GOGOSTART 405 | 10112011, 406 | 11102011, 407 | 1011101110111011, 408 | 11102011, 409 | 2000101020011010, 410 | 1001101010001010, 411 | 10112210, 412 | 30303011, 413 | 20112011, 414 | 11102011, 415 | 1011101110111011, 416 | 11102011, 417 | 2011 418 | #BPMCHANGE 178 419 | #SCROLL 1.04 420 | 20 421 | #BPMCHANGE 168 422 | #SCROLL 1.11 423 | 11, 424 | #MEASURE 5/4 425 | #BPMCHANGE 159 426 | #SCROLL 1 427 | 70000000 428 | #BPMCHANGE 144 429 | 00000000 430 | #BPMCHANGE 126 431 | 00000000 432 | 433 | #GOGOEND 434 | #BPMCHANGE 107 435 | 00000800 436 | #BPMCHANGE 60.61 437 | 00000000, 438 | 439 | #GOGOSTART 440 | #MEASURE 2/4 441 | #BPMCHANGE 186 442 | 22, 443 | #MEASURE 4/4 444 | 1011101110111011, 445 | 11102000, 446 | 1000200011101000, 447 | 1000200011101000, 448 | 1000200011101000, 449 | 1020111010000000, 450 | 1010200011101000, 451 | 1010200011101000, 452 | 1110101110101110, 453 | 1011101000000000, 454 | 1110101110101110, 455 | 10111010 456 | 457 | #GOGOEND 458 | 00000000, 459 | 460 | 461 | #END 462 | 463 | 464 | COURSE:Normal 465 | LEVEL:5 466 | BALLOON:9,10 467 | SCOREINIT:570 468 | SCOREDIFF:157 469 | 470 | 471 | #START 472 | 473 | 474 | #BARLINEOFF 475 | , 476 | 477 | #GOGOSTART 478 | #BARLINEON 479 | 33000000, 480 | 33000000, 481 | 33000000, 482 | 3330, 483 | 10101110, 484 | 10101110, 485 | 6, 486 | 000000000000000008000000000000000000000000000000, 487 | 488 | #GOGOEND 489 | 11, 490 | 1, 491 | 11, 492 | 1, 493 | 11, 494 | 11, 495 | 500000000000000000000000000000000000000000000008, 496 | , 497 | 12, 498 | 1110, 499 | 12, 500 | 1110, 501 | 12, 502 | 12, 503 | 500000000000000000000000000000000000000000000008, 504 | 0022, 505 | 10010010, 506 | 0022, 507 | 10010010, 508 | 0011, 509 | 2211, 510 | 1044, 511 | 3333, 512 | 3, 513 | 514 | #GOGOSTART 515 | 30111010, 516 | 10111000, 517 | 10111010, 518 | 10111000, 519 | 10111010, 520 | 10111000, 521 | 600000000000000000000000000000000008000000000000, 522 | 33304000, 523 | 10111010, 524 | 10111000, 525 | 10111010, 526 | 3330, 527 | 10111010, 528 | 10111000, 529 | 600000000000000000000000000000000008000000000000, 530 | 33304000, 531 | 532 | #GOGOEND 533 | 1110, 534 | 1110, 535 | 3, 536 | 10111000, 537 | 1111, 538 | 10111000, 539 | 6, 540 | 000000000000000000000008000000000000000000000000, 541 | 11, 542 | 1110, 543 | 11, 544 | 1110, 545 | 12, 546 | 1120, 547 | 12, 548 | 1120, 549 | 1120, 550 | 100000000000100000000000600000000000000000000008, 551 | , 552 | 3, 553 | , 554 | , 555 | 3330, 556 | 557 | #GOGOSTART 558 | 10111010, 559 | 10111000, 560 | 600000000000000000000000000000000008000000000000, 561 | 33304000, 562 | 10111010, 563 | 10111000, 564 | 10111010, 565 | 3330, 566 | 10111010, 567 | 10111000, 568 | 600000000000000000000000000000000008000000000000, 569 | 33304000, 570 | 1011 571 | #BPMCHANGE 178 572 | #SCROLL 1.04 573 | 10 574 | #BPMCHANGE 168 575 | #SCROLL 1.11 576 | 10, 577 | #MEASURE 5/4 578 | #BPMCHANGE 159 579 | #SCROLL 1.17 580 | 70000000 581 | #BPMCHANGE 144 582 | #SCROLL 1.29 583 | 00000000 584 | #BPMCHANGE 126 585 | #SCROLL 1.49 586 | 00000000 587 | 588 | #GOGOEND 589 | #BPMCHANGE 107 590 | #SCROLL 1.74 591 | 00000800 592 | #BPMCHANGE 60.61 593 | #SCROLL 3.07 594 | 00000000, 595 | 596 | #GOGOSTART 597 | #MEASURE 2/4 598 | #BPMCHANGE 186 599 | #SCROLL 1 600 | 22, 601 | #MEASURE 4/4 602 | 600000000000000000000000000000000008000000000000, 603 | 33304000, 604 | 10201110, 605 | 10201110, 606 | 10201110, 607 | 10111000, 608 | 10201110, 609 | 10201110, 610 | 6, 611 | 000000000000000008000000000000000000000000000000, 612 | 9, 613 | 0 614 | 615 | #GOGOEND 616 | 8, 617 | 618 | 619 | #END 620 | 621 | 622 | COURSE:Easy 623 | LEVEL:3 624 | BALLOON:5,7,7 625 | SCOREINIT:510 626 | SCOREDIFF:155 627 | 628 | 629 | #START 630 | 631 | 632 | #BARLINEOFF 633 | , 634 | 635 | #GOGOSTART 636 | #BARLINEON 637 | 3, 638 | 3, 639 | 3, 640 | 31, 641 | 1110, 642 | 1110, 643 | 6, 644 | 000000000000000008000000000000000000000000000000, 645 | 646 | #GOGOEND 647 | 1, 648 | , 649 | 1, 650 | , 651 | 1, 652 | 1, 653 | 500000000000000000000000000000000000000000000008, 654 | , 655 | 11, 656 | 1, 657 | 11, 658 | 1, 659 | 12, 660 | 12, 661 | 500000000000000000000000000000000000000000000008, 662 | , 663 | 10010010, 664 | , 665 | 10010010, 666 | , 667 | 12, 668 | 13, 669 | 3333, 670 | 3, 671 | 672 | #GOGOSTART 673 | 12, 674 | 1110, 675 | 12, 676 | 1110, 677 | 12, 678 | 1110, 679 | 600000000000000000000000000008000000000000000000, 680 | 3330, 681 | 12, 682 | 1110, 683 | 12, 684 | 3330, 685 | 12, 686 | 1110, 687 | 600000000000000000000000000008000000000000000000, 688 | 3330, 689 | 690 | #GOGOEND 691 | 1, 692 | 11, 693 | 3, 694 | 1110, 695 | 12, 696 | 12, 697 | 7, 698 | 8, 699 | 11, 700 | 1110, 701 | 11, 702 | 1110, 703 | 1, 704 | 1, 705 | 12, 706 | 1, 707 | 1110, 708 | 100000000000100000000000500000000000000000000008, 709 | , 710 | 3, 711 | , 712 | , 713 | 3330, 714 | 715 | #GOGOSTART 716 | 12, 717 | 1110, 718 | 600000000000000000000000000008000000000000000000, 719 | 3330, 720 | 12, 721 | 1110, 722 | 12, 723 | 3330, 724 | 12, 725 | 1110, 726 | 600000000000000000000000000008000000000000000000, 727 | 3330, 728 | 10 729 | #BPMCHANGE 178 730 | #SCROLL 1.04 731 | 1 732 | #BPMCHANGE 168 733 | #SCROLL 1.1625 734 | 0, 735 | #MEASURE 5/4 736 | #BPMCHANGE 159 737 | #SCROLL 1.17 738 | 70000000 739 | #BPMCHANGE 144 740 | #SCROLL 1.29 741 | 00000000 742 | #BPMCHANGE 126 743 | #SCROLL 1.49 744 | 00000000 745 | 746 | #GOGOEND 747 | #BPMCHANGE 107 748 | #SCROLL 1.74 749 | 00000800 750 | #BPMCHANGE 60.61 751 | #SCROLL 3.07 752 | 00000000, 753 | 754 | #GOGOSTART 755 | #MEASURE 2/4 756 | #BPMCHANGE 186 757 | #SCROLL 1 758 | , 759 | #MEASURE 4/4 760 | 600000000000000000000000000008000000000000000000, 761 | 3330, 762 | 1110, 763 | 1110, 764 | 1110, 765 | 2220, 766 | 1110, 767 | 1110, 768 | 6, 769 | 000000000000000008000000000000000000000000000000, 770 | 9, 771 | 0 772 | #GOGOEND 773 | 8, 774 | 775 | 776 | #END 777 | 778 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > [!CAUTION] 2 | > Due to the [recent, aggressive shift](https://x.com/taiko_kateiyou/status/1935532991863820367) in Bandai Namco's handling of modding tools, and due to the threat of [fraudulent DMCA takedowns](https://github.com/TaikoModding/TekaTeka), development has shifted to an alternate Git host: [**tendokyu.moe**](https://gitea.tendokyu.moe/vivaria/tja2fumen). This GitHub repository will hereby be changed to "Archived" status. 3 | > 4 | > **Note:** The code in the tja2fumen repository deals only with plaintext and unencrypted binary files. The tja2fumen code does not modify game code, it does not use proprietary assets, and it does not use Bandai Namco secrets. In theory, this should keep it safe from DMCA takedown notices. However, theoretical safety does not matter in today's world, so it is better to be safe than sorry. 5 | 6 |   7 |

8 | tja2fumen – TJA chart converter 13 |
14 | tja2fumen is a tool that allows you to convert fan-made Taiko song charts (.tja) into officially-compatible game files (.bin). 15 |

16 | 17 |

18 | Test status (main branch) 19 | GitHub release (with filter) 20 | MIT License 21 | Linting pylint 22 | Linting flake8 23 | Linting mypy 24 |

25 | 26 |

27 | 28 | 29 |

30 | 31 | 32 | 33 | ---- 34 | 35 | > [!IMPORTANT] 36 | > tja2fumen is a tool designed for mod developers. It allows modders to load TJA charts into official games by converting them into Taiko's official binary fumen file format (`.bin`). 37 | > 38 | > If you are not a mod developer, and you just want to play TJAs on Taiko no Tatsujin PC, please install and run [TakoTako](https://github.com/fluto/takotako). (Alternatively, you can also run TakoTako's `TJAConvert.exe` [directly on your TJA files](#tja--audio-conversion).) 39 | 40 | 41 | > [!NOTE] 42 | > #### Replacing tja2bin (TakoTako 3.2.0 and below) 43 | > TakoTako 3.2.0 includes an older, flawed tool called `tja2bin.exe`. If you have downloaded TakoTako 3.2.0, you should replace the old `tja2bin.exe` with the latest version of `tja2fumen.exe`. This will ensure that your TJAs get converted accurately. 44 | > 45 | > You can do this by: 46 | > - Downloading `tja2fumen.exe` from the [releases page](https://github.com/vivaria/tja2fumen/releases). 47 | > - Renaming the file to `tja2bin.exe`. 48 | > - Copying and pasting it into the `{TDMX_INSTALLATION_DIR}/BepInEx/plugins/com.fluto.takotako/` directory, replacing the old `tja2bin.exe`. 49 | 50 | ## Features 51 | 52 | tja2fumen is designed to be an open source alternative to the closed source tja2bin tool that has been floating around various Discord servers. tja2fumen fixes several outstanding tja2bin issues, while providing an open source codebase to modify and learn from. 53 | 54 | - Command line tool to convert `.tja` chart files to official fumen `.bin` files. 55 | - Decodes official fumen `.bin` files (to inspect metadata and note data). 56 | - Fix `.bin` files that were previously converted by `tja2bin` (WIP, see [#65](https://github.com/vivaria/tja2fumen/issues/65)). 57 | - Uses strong development practices (thorough test suite with example charts, type checking). 58 | - Provides an open source resource for the Taiko no Tatsujin fumen file format. 59 | 60 | ## Usage 61 | 62 | ### TJA conversion 63 | 64 | To convert a `.tja` file to `.bin` files, simply download `tja2fumen.exe` and run: 65 | 66 | ```bash 67 | tja2fumen.exe "file.tja" 68 | ``` 69 | 70 | ### TJA + Audio conversion 71 | 72 | `tja2fumen.exe` only converts TJA files. If you want to convert both TJAs _and_ audio (.OGG or .WAV files) to `.bin` files, you can use the TakoTako plugin for the PC version of Taiko no Tatsujin. However, if you don't want to install and run Taiko no Tatsujin on PC, then you can use this simpler method instead: 73 | 74 | 1. Download the [latest release of TakoTako](https://github.com/Fluto/TakoTako/releases). 75 | 2. Extract the `TJAConvert.exe` program into a separate folder. 76 | 3. Download the newest version of `tja2fumen.exe`. Rename it `tja2bin.exe`, then place it in the same folder as `TJAConvert.exe`. 77 | 4. Run the following command: 78 | 79 | ```bash 80 | TJAConvert.exe "path_to_folder_containing_both_tja_and_audio/" 81 | ``` 82 | 83 | `TJAConvert.exe` will convert the audio to CRIWARE HCA packed into ACB container, and then it will call `tja2fumen.exe` to convert the chart files. (This is the exact same conversion you would get by running TakoTako as a BepInEx plugin -- you just have more control.) Note that the output audio is unencrypted, and that ACB audio files are incompatible with any NUS3BANK-based games. 84 | 85 | ### Decoding fumen charts in Python scripts 86 | 87 | If you want to explore the song structure of existing `.bin` files or `.tja` files using Python scripts, run: 88 | 89 | ``` 90 | pip install tja2fumen 91 | ``` 92 | 93 | Then, you can use tja2fumen's Python API as follows: 94 | 95 | ```python 96 | # parse song files 97 | from tja2fumen.parsers import parse_fumen, parse_tja 98 | fumen = parse_fumen("path/to/fumen_file.bin") 99 | tja = parse_tja("path/to/tja_file.tja") 100 | 101 | # convert tja data to fumen data 102 | from tja2fumen.converters import convert_tja_to_fumen 103 | fumen_converted = convert_tja_to_fumen(tja.courses['Oni']) #TJAcourse is under tja.courses so it's necessary to specify which course to be converted 104 | 105 | # modify the FumenCourse object 106 | # - e.g.1: change the timing window header metadata 107 | from tja2fumen.constants import TIMING_WINDOWS 108 | fumen.header.b000_b431_timing_windows = TIMING_WINDOWS['Easy']*36 109 | # - e.g.2: change the note offset values 110 | for measure in fumen.measures: 111 | measure.offset_start += 1_000 # 1000ms == 1s 112 | measure.offset_end += 1_000 113 | 114 | # write the modified fumen back to a .bin file 115 | from tja2fumen.writers import write_fumen 116 | write_fumen("path/to/file.bin", fumen) 117 | ``` 118 | 119 | Please refer to `src/__init__.py` for further example usage of the Python API. 120 | 121 | ## TJA Support 122 | 123 | If there is an unsupported feature that you would like support for, please make a request by [opening a new issue](https://github.com/vivaria/tja2fumen/issues/new). 124 | 125 | ### Supported file formats 126 | 127 | > **Legend**: `✅` = Fully supported, `❌` = Not supported 128 | 129 | | | tja 2 fumen | tja 2 bin | Comment | 130 | |---------------------|-------------|-----------|----------| 131 | | UTF-8 (with BOM) | `✅` | `❌` |   | 132 | | UTF-8 (without BOM) | `✅️` | `✅` |   | 133 | | Shift-JIS | `✅` | `✅` |   | 134 | 135 | ### Supported metadata 136 | 137 | > **Legend**: `✅` = Fully supported, `⚪️` = Ignored, `⚠️` = Incorrect behavior, `❌` = Not supported 138 | 139 | | | tja 2 fumen | tja 2 bin | Comment | 140 | |-----------------------------------------------------------------|-------------|-----------|-------------------------------------------------------------------------| 141 | | `BPM:`, `OFFSET:` | `✅` | `✅` |   | 142 | | `TITLE:`, `SUBTITLE:`, `WAVE:`,
`DEMOSTART:`, etc. | `⚪️` | `⚪️` | The only global metadata needed are `BPM:` and `OFFSET:`.   | 143 | | `COURSE:`, `LEVEL:`, `BALLOON:`,
`SCOREINIT:`, `SCOREDIFF:` | `✅` | `✅` |   | 144 | | `STYLE:` (`Single`, `Double`) | `✅` | `❌` |   | 145 | | `EXAM1:`, `GAUGEINCR:`, `TOTAL:`, etc. | `⚪️` | `⚪️` | Other simulator-specific metadata fields are currently ignored.  | 146 | 147 | ### Supported notes/commands 148 | 149 | > **Legend**: `✅` = Fully supported, `⚪️` = Ignored, `⚠️` = Incorrect behavior, `❌` = Not supported 150 | 151 | | | tja 2 fumen | tja 2 bin | Comment | 152 | |----------------------------------------------|-----------|-----------|--------------------------------------------------------------------------------------------------------------------------------------------------| 153 | | `0`, `1`, `2`, `3`, `4` | `✅` | `⚠️` | tja2fumen will write proper SENOTES (ド, コ, ドン, カ, カッ), see [#41](https://github.com/vivaria/tja2fumen/issues/41). | 154 | | `5008,`, `6008,`, `7008,` | `✅` | `✅` | | 155 | | `9008,` | `✅` | `⚠️` | | 156 | | `9000,`
`9008,` | `⚪️` | `⚠️` | Double Kusudama note treated as 1 drumroll by tja2fumen, but 2 overlapping drumrolls by tja2bin. | 157 | | `A`, `B` | `✅` | `❌` | Multiplayer "hands" notes are valid in fumens, but unrecognized by tja2bin. | 158 | | `C`, `D`, `E`, `F`, `G`, `H`, `I` | `⚠️` | `❌` | Replaced by normal notes/rolls in tja2fumen. | 159 | | `#SENOTECHANGE` | `✅` | `❌` | Recently added. See [#69](https://github.com/vivaria/tja2fumen/issues/69) and [#81](https://github.com/vivaria/tja2fumen/issues/81) for details. | 160 | | `#START`, `#END` | `✅` | `✅` | | 161 | | `#START P1`, `#START P2` | `✅` | `❌` | | 162 | | `#BPMCHANGE` | `✅` | `⚠️` | See [#16](https://github.com/Fluto/TakoTako/issues/16) | 163 | | `#MEASURE` | `✅` | `✅` | | 164 | | `#SCROLL` | `✅` | `✅` | | 165 | | `#GOGOSTART`, `#GOGOEND` | `✅` | `✅` | | 166 | | `#BARLINEOFF`, `#BARLINEON` | `✅` | `✅` | | 167 | | `#DELAY` | `✅` | `❌` | See [#27](https://github.com/Fluto/TakoTako/issues/27) | 168 | | `#BRANCHSTART`, `#BRANCHEND` | `✅` | `✅` | | 169 | | `#N`, `#E`, `#M` | `✅` | `✅` | | 170 | | `#SECTION` | `⚠️` | `❌` | See [#53](https://github.com/vivaria/tja2fumen/issues/53), [#27](https://github.com/Fluto/TakoTako/issues/27) | 171 | | `#LEVELHOLD` | `✅` | `❌` | | 172 | | `#BMSCROLL`, `#LYRIC`,
`#DIRECTION`, etc. | `⚪️` | `❌` | Other simulator-specific chart commands are currently ignored. | 173 | 174 | ## Reporting bugs 175 | 176 | If you've found a `.tja` file that tja2fumen converts incorrectly, please [open a new issue](https://github.com/vivaria/tja2fumen/issues/new) on the tja2fumen repo. 177 | 178 | It is especially important that you attach the song files to the issue. You can do this by adding the song files to a `.zip` (Select files -> Right click -> "Send to" -> "Compressed (zipped) folder"), and then uploading the `.zip` to the issue. This greatly helps me to reproduce and fix any issues. 179 | 180 | ## Building on top of tja2fumen 181 | 182 | If you are a developer looking to add tja2fumen to your project, you have two options: 183 | 184 | 1. For non-Python projects, you can download `tja2fumen.exe` and call it via a system call. 185 | 2. For Python projects, you can install tja2fumen via `pip install tja2fumen`. 186 | 187 | tja2fumen uses a very permissable license ([MIT License](https://choosealicense.com/licenses/mit/)). You are free to distribute and modify tja2fumen, but please include a copy of the MIT License alongside the `tja2fumen.exe` executable if you copy it into your project. 188 | 189 | ## Attribution 190 | 191 | - The fumen-parsing code in this project is based off of a modified copy of the [`readFumen()`](https://github.com/KatieFrogs/fumen-tools/blob/6ff3a2f7f53687f3dd49c5c57fcfc5ccbe3e5a10/fumen2osu/fumen2osu.py#L7-L152) function from the [`fumen2osu.py`](https://github.com/KatieFrogs/fumen-tools/blob/main/fumen2osu/fumen2osu.py) found in @KatieFrogs' [`fumen-tools`](https://github.com/KatieFrogs/fumen-tools) project. 192 | - The TJA-parsing code in this project is a Python translation of the [`parseTJA.js`](https://github.com/WHMHammer/tja-tools/blob/master/src/js/parseTJA.js) file from @WHMHammer's [`tja-tools`](https://github.com/WHMHammer/tja-tools). 193 | - sakurada0291, DDDDDD, U-ros, and others in the Discord for helping to test tja2fumen. :) 194 | -------------------------------------------------------------------------------- /testing/data/linda.tja: -------------------------------------------------------------------------------- 1 | //リンダリンダ 2 | BPM:62 3 | OFFSET:-4.005 4 | 5 | COURSE:Oni 6 | LEVEL:5 7 | 8 | STYLE:Double 9 | BALLOON:32 10 | SCOREINIT:680 11 | SCOREDIFF:187 12 | 13 | 14 | #START P1 15 | 16 | 17 | 0000100010001100, 18 | #BPMCHANGE 61.6047 19 | 0000112200000000, 20 | #BPMCHANGE 63.3481 21 | 00112211, 22 | #BPMCHANGE 62.3355 23 | 1000002200000000, 24 | #BPMCHANGE 61.3590 25 | 0000101100002200, 26 | #BPMCHANGE 60.4130 27 | 0000112200000000, 28 | #BPMCHANGE 63.2111 29 | 0000101011200001, 30 | #SCROLL 1.07 31 | #BPMCHANGE 59.1014 32 | 11220000, 33 | 34 | #GOGOSTART 35 | #SCROLL 1 36 | #BPMCHANGE 193.8642 37 | 3333, 38 | #BPMCHANGE 201.6868 39 | 10201120, 40 | 3112, 41 | #BPMCHANGE 196.8317 42 | 11101110, 43 | #BPMCHANGE 197.7314 44 | 3333, 45 | 10201120, 46 | 3112, 47 | #BPMCHANGE 198.4705 48 | 1010100010101111, 49 | 50 | #GOGOEND 51 | #BPMCHANGE 197.2646 52 | 1000200010102010, 53 | #BPMCHANGE 198.0002 54 | 10221120, 55 | 10221020, 56 | #BPMCHANGE 195.8084 57 | 10221120, 58 | #BPMCHANGE 197.9022 59 | 1000200010102010, 60 | 10221120, 61 | #BPMCHANGE 199.0340 62 | 10221020, 63 | #BPMCHANGE 196.7839 64 | 1010100010001111, 65 | #BPMCHANGE 197.9022 66 | 1000200010102010, 67 | 10221120, 68 | 10221020, 69 | 1000202010102000, 70 | 1000200010102010, 71 | #BPMCHANGE 198.5072 72 | 10221120, 73 | #BPMCHANGE 200.2918 74 | 10221020, 75 | #BPMCHANGE 195.5474 76 | 11111111, 77 | 78 | #GOGOSTART 79 | #BPMCHANGE 198.4167 80 | 3333, 81 | 10201120, 82 | 3112, 83 | #BPMCHANGE 198.0002 84 | 11101110, 85 | #BPMCHANGE 199.1761 86 | 3333, 87 | #BPMCHANGE 197.8324 88 | 10201120, 89 | #BPMCHANGE 199.3150 90 | 1112, 91 | #BPMCHANGE 197.5406 92 | 11, 93 | 94 | #GOGOEND 95 | #BPMCHANGE 195.2769 96 | 9, 97 | #BPMCHANGE 198.3065 98 | , 99 | 08, 100 | , 101 | #BPMCHANGE 198.0002 102 | 10112211, 103 | #BPMCHANGE 199.9433 104 | 10221122, 105 | #BPMCHANGE 197.3613 106 | 10112211, 107 | 1000200010101111, 108 | 10221020, 109 | #BPMCHANGE 196.1130 110 | 10221120, 111 | #BPMCHANGE 198.4777 112 | 1000200010102010, 113 | 10221120, 114 | 10221020, 115 | 10221120, 116 | #BPMCHANGE 198.0002 117 | 1000200010102010, 118 | #BPMCHANGE 196.4662 119 | 1000222010002220, 120 | #BPMCHANGE 197.6467 121 | 10221020, 122 | 10221120, 123 | 1000200010102010, 124 | 10221120, 125 | #BPMCHANGE 200.1027 126 | 10221020, 127 | #BPMCHANGE 194.7021 128 | 10221120, 129 | #BPMCHANGE 198.2134 130 | 3333, 131 | #BPMCHANGE 196.0073 132 | 1110111011111110, 133 | 134 | #GOGOSTART 135 | #BPMCHANGE 201.0676 136 | 3333, 137 | 10201120, 138 | #BPMCHANGE 198.0002 139 | 3112, 140 | 10201120, 141 | 3333, 142 | 10201120, 143 | 3111, 144 | 1111, 145 | 146 | #GOGOEND 147 | #BPMCHANGE 196.1130 148 | 6, 149 | #BPMCHANGE 198.9588 150 | 0008, 151 | #BPMCHANGE 196.0221 152 | 10201120, 153 | #BPMCHANGE 199.4502 154 | 11111111, 155 | #BPMCHANGE 170 156 | #SCROLL 1.17 157 | #DELAY 0.0707 158 | 3, 159 | 160 | 161 | #END 162 | 163 | 164 | #START P2 165 | 166 | 167 | 0000100010001100, 168 | #BPMCHANGE 61.6047 169 | 0000112200000000, 170 | #BPMCHANGE 63.3481 171 | 00112211, 172 | #BPMCHANGE 62.3355 173 | 1000002200000000, 174 | #BPMCHANGE 61.3590 175 | 0000101100002200, 176 | #BPMCHANGE 60.4130 177 | 0000112200000000, 178 | #BPMCHANGE 63.2111 179 | 0000101011200001, 180 | #SCROLL 1.07 181 | #BPMCHANGE 59.1014 182 | 11220000, 183 | 184 | #GOGOSTART 185 | #SCROLL 1 186 | #BPMCHANGE 193.8642 187 | 3333, 188 | #BPMCHANGE 201.6868 189 | 10201120, 190 | 3112, 191 | #BPMCHANGE 196.8317 192 | 11101110, 193 | #BPMCHANGE 197.7314 194 | 3333, 195 | 10201120, 196 | 3112, 197 | #BPMCHANGE 198.4705 198 | 1010100010101111, 199 | 200 | #GOGOEND 201 | #BPMCHANGE 197.2646 202 | 10221020, 203 | #BPMCHANGE 198.0002 204 | 10221120, 205 | 10201121, 206 | #BPMCHANGE 195.8084 207 | 10221120, 208 | #BPMCHANGE 197.9022 209 | 10221020, 210 | 10221120, 211 | #BPMCHANGE 199.0340 212 | 10201121, 213 | #BPMCHANGE 196.7839 214 | 1010100010001111, 215 | #BPMCHANGE 197.9022 216 | 10221020, 217 | 10221120, 218 | 10201121, 219 | 10221120, 220 | 10221020, 221 | #BPMCHANGE 198.5072 222 | 10221120, 223 | #BPMCHANGE 200.2918 224 | 10221020, 225 | #BPMCHANGE 195.5474 226 | 11111111, 227 | 228 | #GOGOSTART 229 | #BPMCHANGE 198.4167 230 | 3333, 231 | 10201120, 232 | 3112, 233 | #BPMCHANGE 198.0002 234 | 11101110, 235 | #BPMCHANGE 199.1761 236 | 3333, 237 | #BPMCHANGE 197.8324 238 | 10201120, 239 | #BPMCHANGE 199.3150 240 | 1112, 241 | #BPMCHANGE 197.5406 242 | 11, 243 | 244 | #GOGOEND 245 | #BPMCHANGE 195.2769 246 | 9, 247 | #BPMCHANGE 198.3065 248 | , 249 | 08, 250 | , 251 | #BPMCHANGE 198.0002 252 | 10112211, 253 | #BPMCHANGE 199.9433 254 | 10221122, 255 | #BPMCHANGE 197.3613 256 | 10112211, 257 | 1000200010101111, 258 | 10201121, 259 | #BPMCHANGE 196.1130 260 | 10221120, 261 | #BPMCHANGE 198.4777 262 | 10221020, 263 | 10221120, 264 | 10201121, 265 | 10221120, 266 | #BPMCHANGE 198.0002 267 | 10221020, 268 | #BPMCHANGE 196.4662 269 | 1000222010002220, 270 | #BPMCHANGE 197.6467 271 | 10201121, 272 | 10221120, 273 | 10221020, 274 | 10221120, 275 | #BPMCHANGE 200.1027 276 | 10201121, 277 | #BPMCHANGE 194.7021 278 | 10221120, 279 | #BPMCHANGE 198.2134 280 | 3333, 281 | #BPMCHANGE 196.0073 282 | 1110111011111110, 283 | 284 | #GOGOSTART 285 | #BPMCHANGE 201.0676 286 | 3333, 287 | 10201120, 288 | #BPMCHANGE 198.0002 289 | 3112, 290 | 10201120, 291 | 3333, 292 | 10201120, 293 | 3111, 294 | 1111, 295 | 296 | #GOGOEND 297 | #BPMCHANGE 196.1130 298 | 6, 299 | #BPMCHANGE 198.9588 300 | 0008, 301 | #BPMCHANGE 196.0221 302 | 10201120, 303 | #BPMCHANGE 199.4502 304 | 11111111, 305 | #BPMCHANGE 170 306 | #SCROLL 1.17 307 | #DELAY 0.0707 308 | 3, 309 | 310 | 311 | #END 312 | 313 | 314 | STYLE:Single 315 | BALLOON:32 316 | SCOREINIT:710 317 | SCOREDIFF:200 318 | 319 | 320 | #START 321 | 322 | 323 | 0000100010001100, 324 | #BPMCHANGE 61.6047 325 | 0000112200000000, 326 | #BPMCHANGE 63.3481 327 | 00112211, 328 | #BPMCHANGE 62.3355 329 | 1000002200000000, 330 | #BPMCHANGE 61.3590 331 | 0000101100002200, 332 | #BPMCHANGE 60.4130 333 | 0000112200000000, 334 | #BPMCHANGE 63.2111 335 | 0000101011200001, 336 | #SCROLL 1.07 337 | #BPMCHANGE 59.1014 338 | 11220000, 339 | 340 | #GOGOSTART 341 | #SCROLL 1 342 | #BPMCHANGE 193.8642 343 | 3333, 344 | #BPMCHANGE 201.6868 345 | 10201120, 346 | 3112, 347 | #BPMCHANGE 196.8317 348 | 11101110, 349 | #BPMCHANGE 197.7314 350 | 3333, 351 | 10201120, 352 | 3112, 353 | #BPMCHANGE 198.4705 354 | 1010100010101111, 355 | 356 | #GOGOEND 357 | #BPMCHANGE 197.2646 358 | 1000200010102010, 359 | #BPMCHANGE 198.0002 360 | 10221120, 361 | 10221020, 362 | #BPMCHANGE 195.8084 363 | 10221120, 364 | #BPMCHANGE 197.9022 365 | 1000200010102010, 366 | 10221120, 367 | #BPMCHANGE 199.0340 368 | 10221020, 369 | #BPMCHANGE 196.7839 370 | 1010100010001111, 371 | #BPMCHANGE 197.9022 372 | 1000200010102010, 373 | 10221120, 374 | 10221020, 375 | 1000202010102000, 376 | 1000200010102010, 377 | #BPMCHANGE 198.5072 378 | 10221120, 379 | #BPMCHANGE 200.2918 380 | 10221020, 381 | #BPMCHANGE 195.5474 382 | 11111111, 383 | 384 | #GOGOSTART 385 | #BPMCHANGE 198.4167 386 | 3333, 387 | 10201120, 388 | 3112, 389 | #BPMCHANGE 198.0002 390 | 11101110, 391 | #BPMCHANGE 199.1761 392 | 3333, 393 | #BPMCHANGE 197.8324 394 | 10201120, 395 | #BPMCHANGE 199.3150 396 | 1112, 397 | #BPMCHANGE 197.5406 398 | 11, 399 | 400 | #GOGOEND 401 | #BPMCHANGE 195.2769 402 | 9, 403 | #BPMCHANGE 198.3065 404 | , 405 | 08, 406 | , 407 | #BPMCHANGE 198.0002 408 | 10112211, 409 | #BPMCHANGE 199.9433 410 | 10221122, 411 | #BPMCHANGE 197.3613 412 | 10112211, 413 | 1000200010101111, 414 | 10221020, 415 | #BPMCHANGE 196.1130 416 | 10221120, 417 | #BPMCHANGE 198.4777 418 | 1000200010102010, 419 | 10221120, 420 | 10221020, 421 | 10221120, 422 | #BPMCHANGE 198.0002 423 | 1000200010102010, 424 | #BPMCHANGE 196.4662 425 | 1000222010002220, 426 | #BPMCHANGE 197.6467 427 | 10221020, 428 | 10221120, 429 | 1000200010102010, 430 | 10221120, 431 | #BPMCHANGE 200.1027 432 | 10221020, 433 | #BPMCHANGE 194.7021 434 | 10221120, 435 | #BPMCHANGE 198.2134 436 | 3333, 437 | #BPMCHANGE 196.0073 438 | 1110111011111110, 439 | 440 | #GOGOSTART 441 | #BPMCHANGE 201.0676 442 | 3333, 443 | 10201120, 444 | #BPMCHANGE 198.0002 445 | 3112, 446 | 10201120, 447 | 3333, 448 | 10201120, 449 | 3111, 450 | 1111, 451 | 452 | #GOGOEND 453 | #BPMCHANGE 196.1130 454 | 6, 455 | #BPMCHANGE 198.9588 456 | 0008, 457 | #BPMCHANGE 196.0221 458 | 10201120, 459 | #BPMCHANGE 199.4502 460 | 11111111, 461 | #BPMCHANGE 170 462 | #SCROLL 1.17 463 | #DELAY 0.0707 464 | 3, 465 | 466 | 467 | #END 468 | 469 | 470 | COURSE:Hard 471 | LEVEL:5 472 | BALLOON:25 473 | SCOREINIT:720 474 | SCOREDIFF:215 475 | 476 | #START 477 | 0000100010001100, 478 | #BPMCHANGE 61.6047 479 | 0000111100000000, 480 | #BPMCHANGE 63.3481 481 | 00112211, 482 | #BPMCHANGE 62.3355 483 | 1000002200000000, 484 | #BPMCHANGE 61.3590 485 | 0000101100002200, 486 | #BPMCHANGE 60.4130 487 | 0000111100000000, 488 | #BPMCHANGE 63.2111 489 | 0000101011100001, 490 | #SCROLL 1.07 491 | #BPMCHANGE 59.1014 492 | 11220000, 493 | 494 | #GOGOSTART 495 | #SCROLL 1 496 | #BPMCHANGE 193.8642 497 | 3333, 498 | #BPMCHANGE 201.6868 499 | 1212, 500 | 1111, 501 | #BPMCHANGE 196.8317 502 | 5008, 503 | #BPMCHANGE 197.7314 504 | 3333, 505 | 1212, 506 | 1111, 507 | #BPMCHANGE 198.4705 508 | 50081010, 509 | 510 | #GOGOEND 511 | #BPMCHANGE 197.2646 512 | 10101120, 513 | #BPMCHANGE 198.0002 514 | 10101120, 515 | 10111020, 516 | #BPMCHANGE 195.8084 517 | 1110, 518 | #BPMCHANGE 197.9022 519 | 10101120, 520 | 10101120, 521 | #BPMCHANGE 199.0340 522 | 10111020, 523 | #BPMCHANGE 196.7839 524 | 1210, 525 | #BPMCHANGE 197.9022 526 | 10101120, 527 | 10101120, 528 | 10111020, 529 | 1110, 530 | 10101120, 531 | #BPMCHANGE 198.5072 532 | 10101120, 533 | #BPMCHANGE 200.2918 534 | 1111, 535 | #BPMCHANGE 195.5474 536 | 11115008, 537 | 538 | #GOGOSTART 539 | #BPMCHANGE 198.4167 540 | 3333, 541 | 1212, 542 | 1112, 543 | #BPMCHANGE 198.0002 544 | 5008, 545 | #BPMCHANGE 199.1761 546 | 3333, 547 | #BPMCHANGE 197.8324 548 | 1212, 549 | #BPMCHANGE 199.3150 550 | 1111, 551 | #BPMCHANGE 197.5406 552 | 11, 553 | 554 | #GOGOEND 555 | #BPMCHANGE 195.2769 556 | 9, 557 | #BPMCHANGE 198.3065 558 | , 559 | , 560 | 98, 561 | #BPMCHANGE 198.0002 562 | 10101110, 563 | #BPMCHANGE 199.9433 564 | 10101110, 565 | #BPMCHANGE 197.3613 566 | 10101110, 567 | 10105008, 568 | 10111020, 569 | #BPMCHANGE 196.1130 570 | 10101120, 571 | #BPMCHANGE 198.4777 572 | 10101120, 573 | 1110, 574 | 10111020, 575 | 10101120, 576 | #BPMCHANGE 198.0002 577 | 10101120, 578 | #BPMCHANGE 196.4662 579 | 1000111010001110, 580 | #BPMCHANGE 197.6467 581 | 10111020, 582 | 10101120, 583 | 10101120, 584 | 1110, 585 | #BPMCHANGE 200.1027 586 | 10111020, 587 | #BPMCHANGE 194.7021 588 | 10101120, 589 | #BPMCHANGE 198.2134 590 | 3333, 591 | #BPMCHANGE 196.0073 592 | 11115008, 593 | 594 | #GOGOSTART 595 | #BPMCHANGE 201.0676 596 | 3333, 597 | 1212, 598 | #BPMCHANGE 198.0002 599 | 1111, 600 | 5008, 601 | 3333, 602 | 1212, 603 | 1111, 604 | 33, 605 | 606 | #GOGOEND 607 | #BPMCHANGE 196.1130 608 | 6, 609 | #BPMCHANGE 198.9588 610 | 08, 611 | #BPMCHANGE 196.0221 612 | 1111, 613 | #BPMCHANGE 199.4502 614 | 11101110, 615 | #BPMCHANGE 170 616 | #SCROLL 1.17 617 | #DELAY 0.0707 618 | 3, 619 | #DELAY 0 620 | , 621 | , 622 | #END 623 | 624 | COURSE:Normal 625 | LEVEL:6 626 | BALLOON:20 627 | SCOREINIT:710 628 | SCOREDIFF:215 629 | 630 | #START 631 | 0111, 632 | #BPMCHANGE 61.6047 633 | 0000101100000000, 634 | #BPMCHANGE 63.3481 635 | 0111, 636 | #BPMCHANGE 62.3355 637 | 1000002200000000, 638 | #BPMCHANGE 61.3590 639 | 0111, 640 | #BPMCHANGE 60.4130 641 | 0000101100000000, 642 | #BPMCHANGE 63.2111 643 | 0111, 644 | #SCROLL 1.07 645 | #BPMCHANGE 59.1014 646 | 11220000, 647 | 648 | #GOGOSTART 649 | #SCROLL 1 650 | #BPMCHANGE 193.8642 651 | 3333, 652 | #BPMCHANGE 201.6868 653 | 1120, 654 | 1111, 655 | #BPMCHANGE 196.8317 656 | 5008, 657 | #BPMCHANGE 197.7314 658 | 3333, 659 | 1120, 660 | 1111, 661 | #BPMCHANGE 198.4705 662 | 11, 663 | 664 | #GOGOEND 665 | #BPMCHANGE 197.2646 666 | 10001110, 667 | #BPMCHANGE 198.0002 668 | 10101110, 669 | 10001110, 670 | #BPMCHANGE 195.8084 671 | 10101110, 672 | #BPMCHANGE 197.9022 673 | 10001110, 674 | 10101110, 675 | #BPMCHANGE 199.0340 676 | 10001110, 677 | #BPMCHANGE 196.7839 678 | 22202000, 679 | #BPMCHANGE 197.9022 680 | 10001110, 681 | 10101110, 682 | 10001110, 683 | 10101110, 684 | 10001110, 685 | #BPMCHANGE 198.5072 686 | 10101110, 687 | #BPMCHANGE 200.2918 688 | 1111, 689 | #BPMCHANGE 195.5474 690 | 22202000, 691 | 692 | #GOGOSTART 693 | #BPMCHANGE 198.4167 694 | 3333, 695 | 1120, 696 | 1111, 697 | #BPMCHANGE 198.0002 698 | 5008, 699 | #BPMCHANGE 199.1761 700 | 3333, 701 | #BPMCHANGE 197.8324 702 | 1120, 703 | #BPMCHANGE 199.3150 704 | 1111, 705 | #BPMCHANGE 197.5406 706 | 11, 707 | 708 | #GOGOEND 709 | #BPMCHANGE 195.2769 710 | 9, 711 | #BPMCHANGE 198.3065 712 | , 713 | 98, 714 | , 715 | #BPMCHANGE 198.0002 716 | 10101110, 717 | #BPMCHANGE 199.9433 718 | 10101110, 719 | #BPMCHANGE 197.3613 720 | 10101110, 721 | 1, 722 | 10001110, 723 | #BPMCHANGE 196.1130 724 | 10101110, 725 | #BPMCHANGE 198.4777 726 | 10001110, 727 | 10101110, 728 | 10001110, 729 | 10101110, 730 | #BPMCHANGE 198.0002 731 | 10001110, 732 | #BPMCHANGE 196.4662 733 | 1212, 734 | #BPMCHANGE 197.6467 735 | 10001110, 736 | 10101110, 737 | 10001110, 738 | 10101110, 739 | #BPMCHANGE 200.1027 740 | 10001110, 741 | #BPMCHANGE 194.7021 742 | 10101110, 743 | #BPMCHANGE 198.2134 744 | 1122, 745 | #BPMCHANGE 196.0073 746 | 22202000, 747 | 748 | #GOGOSTART 749 | #BPMCHANGE 201.0676 750 | 3333, 751 | 1120, 752 | #BPMCHANGE 198.0002 753 | 1111, 754 | 5008, 755 | 3333, 756 | 1120, 757 | 1111, 758 | 11, 759 | 760 | #GOGOEND 761 | #BPMCHANGE 196.1130 762 | 5, 763 | #BPMCHANGE 198.9588 764 | 08, 765 | #BPMCHANGE 196.0221 766 | 1111, 767 | #BPMCHANGE 199.4502 768 | 11101110, 769 | #BPMCHANGE 170 770 | #SCROLL 1.17 771 | #DELAY 0.0707 772 | 3, 773 | #DELAY 0 774 | , 775 | , 776 | #END 777 | 778 | COURSE:Easy 779 | LEVEL:4 780 | BALLOON:18 781 | SCOREINIT:710 782 | SCOREDIFF:287 783 | 784 | #START 785 | 0111, 786 | #BPMCHANGE 61.6047 787 | 0100, 788 | #BPMCHANGE 63.3481 789 | 0111, 790 | #BPMCHANGE 62.3355 791 | 1, 792 | #BPMCHANGE 61.3590 793 | 0111, 794 | #BPMCHANGE 60.4130 795 | 0100, 796 | #BPMCHANGE 63.2111 797 | 0111, 798 | #SCROLL 1.07 799 | #BPMCHANGE 59.1014 800 | 1, 801 | 802 | #GOGOSTART 803 | #SCROLL 1 804 | #BPMCHANGE 193.8642 805 | 33, 806 | #BPMCHANGE 201.6868 807 | 1110, 808 | 11, 809 | #BPMCHANGE 196.8317 810 | 5008, 811 | #BPMCHANGE 197.7314 812 | 33, 813 | 1110, 814 | 11, 815 | #BPMCHANGE 198.4705 816 | 58, 817 | 818 | #GOGOEND 819 | #BPMCHANGE 197.2646 820 | 11, 821 | #BPMCHANGE 198.0002 822 | 1100, 823 | 1011, 824 | #BPMCHANGE 195.8084 825 | 2200, 826 | #BPMCHANGE 197.9022 827 | 11, 828 | 1100, 829 | #BPMCHANGE 199.0340 830 | 11, 831 | #BPMCHANGE 196.7839 832 | 2220, 833 | #BPMCHANGE 197.9022 834 | 1011, 835 | 1100, 836 | 11, 837 | 2200, 838 | 1011, 839 | #BPMCHANGE 198.5072 840 | 1100, 841 | #BPMCHANGE 200.2918 842 | 11, 843 | #BPMCHANGE 195.5474 844 | 2220, 845 | 846 | #GOGOSTART 847 | #BPMCHANGE 198.4167 848 | 33, 849 | 1110, 850 | 11, 851 | #BPMCHANGE 198.0002 852 | 5008, 853 | #BPMCHANGE 199.1761 854 | 33, 855 | #BPMCHANGE 197.8324 856 | 1110, 857 | #BPMCHANGE 199.3150 858 | 11, 859 | #BPMCHANGE 197.5406 860 | 11, 861 | 862 | #GOGOEND 863 | #BPMCHANGE 195.2769 864 | 9, 865 | #BPMCHANGE 198.3065 866 | , 867 | 09, 868 | 8, 869 | #BPMCHANGE 198.0002 870 | 11, 871 | #BPMCHANGE 199.9433 872 | 1100, 873 | #BPMCHANGE 197.3613 874 | 11, 875 | 1100, 876 | 11, 877 | #BPMCHANGE 196.1130 878 | 1100, 879 | #BPMCHANGE 198.4777 880 | 1011, 881 | 2200, 882 | 11, 883 | 1100, 884 | #BPMCHANGE 198.0002 885 | 11, 886 | #BPMCHANGE 196.4662 887 | 33, 888 | #BPMCHANGE 197.6467 889 | 1011, 890 | 1100, 891 | 11, 892 | 2200, 893 | #BPMCHANGE 200.1027 894 | 1011, 895 | #BPMCHANGE 194.7021 896 | 1100, 897 | #BPMCHANGE 198.2134 898 | 1111, 899 | #BPMCHANGE 196.0073 900 | 1, 901 | 902 | #GOGOSTART 903 | #BPMCHANGE 201.0676 904 | 33, 905 | 1110, 906 | #BPMCHANGE 198.0002 907 | 33, 908 | 5008, 909 | 33, 910 | 1110, 911 | 11, 912 | 11, 913 | 914 | #GOGOEND 915 | #BPMCHANGE 196.1130 916 | 5, 917 | #BPMCHANGE 198.9588 918 | 8, 919 | #BPMCHANGE 196.0221 920 | 11, 921 | #BPMCHANGE 199.4502 922 | 1111, 923 | #BPMCHANGE 170 924 | #SCROLL 1.17 925 | #DELAY 0.0707 926 | 3, 927 | #DELAY 0 928 | , 929 | , 930 | #END 931 | -------------------------------------------------------------------------------- /src/tja2fumen/classes.py: -------------------------------------------------------------------------------- 1 | """ 2 | Dataclasses used to represent song courses, branches, measures, and notes. 3 | """ 4 | 5 | import csv 6 | import os 7 | import struct 8 | from typing import Any, List, Dict, Tuple 9 | 10 | from dataclasses import dataclass, field, fields 11 | 12 | from tja2fumen.constants import BRANCH_NAMES, TIMING_WINDOWS 13 | 14 | 15 | @dataclass() 16 | class TJAData: 17 | """Contains the information for a single note or single command.""" 18 | name: str 19 | value: str 20 | pos: int # For TJAs, 'pos' is stored as an int rather than in milliseconds 21 | 22 | 23 | @dataclass() 24 | class TJAMeasure: 25 | """Contains all the data in a single TJA measure (denoted by ',').""" 26 | notes: List[str] = field(default_factory=list) 27 | events: List[TJAData] = field(default_factory=list) 28 | combined: List[TJAData] = field(default_factory=list) 29 | 30 | 31 | @dataclass() 32 | class TJACourse: 33 | """Contains all the data in a single TJA `COURSE:` section.""" 34 | bpm: float 35 | offset: float 36 | course: str 37 | level: int = 0 38 | balloon: List[int] = field(default_factory=list) 39 | score_init: int = 0 40 | score_diff: int = 0 41 | data: List[str] = field(default_factory=list) 42 | branches: Dict[str, List[TJAMeasure]] = field(default_factory=dict) 43 | 44 | 45 | @dataclass() 46 | class TJASong: 47 | """Contains all the data in a single TJA (`.tja`) chart file.""" 48 | bpm: float 49 | offset: float 50 | courses: Dict[str, TJACourse] 51 | 52 | 53 | @dataclass() 54 | class TJAMeasureProcessed: 55 | """ 56 | Contains all the data in a single TJA measure (denoted by ','), but with 57 | all `#COMMAND` lines processed, and their values stored as attributes. 58 | 59 | ((Note: Because only one BPM/SCROLL/GOGO value can be stored per measure, 60 | any TJA measures with mid-measure commands must be split up. So, the 61 | number of `TJAMeasureProcessed` objects will often be greater than 62 | the number of `TJAMeasure` objects for a given song.)) 63 | """ 64 | bpm: float 65 | scroll: float 66 | gogo: bool 67 | barline: bool 68 | time_sig: List[int] 69 | subdivisions: int 70 | pos_start: int = 0 71 | pos_end: int = 0 72 | delay: float = 0.0 73 | section: bool = False 74 | levelhold: bool = False 75 | senote: str = '' 76 | branch_type: str = '' 77 | branch_cond: Tuple[float, float] = (0.0, 0.0) 78 | notes: List[TJAData] = field(default_factory=list) 79 | 80 | 81 | @dataclass() 82 | class FumenNote: 83 | """Contains all the byte values for a single Fumen note.""" 84 | note_type: str = '' 85 | pos: float = 0.0 86 | pos_abs: float = 0.0 87 | diff: int = 0 88 | score_init: int = 0 89 | score_diff: int = 0 90 | padding: float = 0.0 91 | item: int = 0 92 | duration: float = 0.0 93 | multimeasure: bool = False 94 | hits: int = 0 95 | hits_padding: int = 0 96 | drumroll_bytes: bytes = b'\x00\x00\x00\x00\x00\x00\x00\x00' 97 | manually_set: bool = False 98 | 99 | 100 | @dataclass() 101 | class FumenBranch: 102 | """Contains all the data in a single Fumen branch.""" 103 | length: int = 0 104 | speed: float = 0.0 105 | padding: int = 0 106 | notes: List[FumenNote] = field(default_factory=list) 107 | 108 | 109 | @dataclass() 110 | class FumenMeasure: 111 | """Contains all the data in a single Fumen measure.""" 112 | bpm: float = 0.0 113 | offset_start: float = 0.0 114 | offset_end: float = 0.0 115 | duration: float = 0.0 116 | gogo: bool = False 117 | barline: bool = True 118 | branch_info: List[int] = field(default_factory=lambda: [-1] * 6) 119 | branches: Dict[str, FumenBranch] = field( 120 | default_factory=lambda: {b: FumenBranch() for b in BRANCH_NAMES} 121 | ) 122 | padding1: int = 0 123 | padding2: int = 0 124 | 125 | def set_duration(self, 126 | time_sig: List[int], 127 | measure_length: int, 128 | subdivisions: int) -> None: 129 | """Compute the millisecond duration of the measure.""" 130 | # First, we compute the duration for a full 4/4 measure. 131 | full_duration = 4 * 60_000 / self.bpm 132 | # Next, we adjust this duration based on both: 133 | # 1. The *actual* measure size (e.g. #MEASURE 1/8, 5/4, etc.) 134 | # 2. Whether this is a "submeasure" (i.e. whether it contains 135 | # mid-measure commands, which split up the measure) 136 | # - If this is a submeasure, then `measure_length` will be 137 | # less than the total number of subdivisions. 138 | # - In other words, `measure_ratio` will be less than 1.0. 139 | measure_size = time_sig[0] / time_sig[1] 140 | measure_ratio = ( 141 | 1.0 if subdivisions == 0.0 # Avoid DivisionByZeroErrors 142 | else (measure_length / subdivisions) 143 | ) 144 | self.duration = full_duration * measure_size * measure_ratio 145 | 146 | def set_first_ms_offsets(self, song_offset: float) -> None: 147 | """Compute the ms offsets for the start/end of the first measure.""" 148 | # First, start with song's OFFSET: metadata 149 | self.offset_start = song_offset * -1 * 1000 # s -> ms 150 | # Then, subtract a full 4/4 measure for the current BPM 151 | self.offset_start -= (4 * 60_000 / self.bpm) 152 | # Compute the end offset by adding the duration to the start offset 153 | self.offset_end = self.offset_start + self.duration 154 | 155 | def set_ms_offsets(self, 156 | delay: float, 157 | prev_measure: 'FumenMeasure') -> None: 158 | """Compute the ms offsets for the start/end of a given measure.""" 159 | # First, start with the end timing of the previous measure 160 | self.offset_start = prev_measure.offset_end 161 | # Add any #DELAY commands 162 | self.offset_start += delay 163 | # Adjust the start timing to account for #BPMCHANGE commands 164 | # (!!! Discovered by tana :3 !!!) 165 | self.offset_start += (4 * 60_000 / prev_measure.bpm) 166 | self.offset_start -= (4 * 60_000 / self.bpm) 167 | # Compute the end offset by adding the duration to the start offset 168 | self.offset_end = self.offset_start + self.duration 169 | 170 | def set_branch_info(self, 171 | branch_type: str, 172 | branch_cond: Tuple[float, float], 173 | branch_points_total: int, 174 | current_branch: str, 175 | has_levelhold: bool) -> None: 176 | """Compute the values that represent branching/diverge conditions.""" 177 | # If levelhold is set, force the branch to stay the same, 178 | # regardless of the value of the current branch condition. 179 | if has_levelhold: 180 | if current_branch == 'normal': 181 | self.branch_info[0:2] = [999, 999] # Forces fail/fail 182 | elif current_branch == 'professional': 183 | self.branch_info[2:4] = [0, 999] # Forces pass/fail 184 | elif current_branch == 'master': 185 | self.branch_info[4:6] = [0, 0] # Forces pass/pass 186 | 187 | # Handle branch conditions for percentage accuracy 188 | # There are three cases for interpreting #BRANCHSTART p: 189 | # 1. Percentage is between 0% and 100% 190 | # 2. Percentage is above 100% (guaranteed level down) 191 | # 3. Percentage is 0% (guaranteed level up) 192 | elif branch_type == 'p': 193 | vals = [] 194 | for percent in branch_cond: 195 | if 0 < percent <= 1: 196 | vals.append(int(branch_points_total * percent)) 197 | elif percent > 1: 198 | vals.append(999) 199 | else: 200 | vals.append(0) 201 | if current_branch == 'normal': 202 | self.branch_info[0:2] = vals 203 | elif current_branch == 'professional': 204 | self.branch_info[2:4] = vals 205 | elif current_branch == 'master': 206 | self.branch_info[4:6] = vals 207 | 208 | # Handle branch conditions for drumroll accuracy 209 | # There are three cases for interpreting #BRANCHSTART r: 210 | # 1. It's the first branching condition. 211 | # 2. It's not the first branching condition, but it 212 | # has a #SECTION command to reset the accuracy. 213 | # 3. It's not the first branching condition, and it 214 | # doesn't have a #SECTION command. 215 | elif branch_type == 'r': 216 | vals = [int(v) for v in branch_cond] 217 | if current_branch == 'normal': 218 | self.branch_info[0:2] = vals 219 | elif current_branch == 'professional': 220 | self.branch_info[2:4] = vals 221 | elif current_branch == 'master': 222 | self.branch_info[4:6] = vals 223 | 224 | 225 | @dataclass() 226 | class FumenHeader: 227 | """Contains all the byte values for a Fumen chart file's header.""" 228 | order: str = "<" 229 | b000_b431_timing_windows: Tuple[float, ...] = (0.0, 0.0, 0.0)*36 230 | b432_b435_has_branches: int = 0 231 | b436_b439_hp_max: int = 10000 232 | b440_b443_hp_clear: int = 8000 233 | b444_b447_hp_gain_good: int = 10 234 | b448_b451_hp_gain_ok: int = 5 235 | b452_b455_hp_loss_bad: int = -20 236 | b456_b459_normal_normal_ratio: int = 65536 237 | b460_b463_normal_professional_ratio: int = 65536 238 | b464_b467_normal_master_ratio: int = 65536 239 | b468_b471_branch_pts_good: int = 20 240 | b472_b475_branch_pts_ok: int = 10 241 | b476_b479_branch_pts_bad: int = 0 242 | b480_b483_branch_pts_drumroll: int = 1 243 | b484_b487_branch_pts_good_big: int = 20 244 | b488_b491_branch_pts_ok_big: int = 10 245 | b492_b495_branch_pts_drumroll_big: int = 1 246 | b496_b499_branch_pts_balloon: int = 30 247 | b500_b503_branch_pts_kusudama: int = 30 248 | b504_b507_branch_pts_unknown: int = 20 249 | b508_b511_dummy_data: int = 12345678 250 | b512_b515_number_of_measures: int = 0 251 | b516_b519_unknown_data: int = 0 252 | 253 | def parse_header_values(self, raw_bytes: bytes) -> None: 254 | """Parse a raw string of 520 bytes to get the header values.""" 255 | self._parse_order(raw_bytes) 256 | raw = raw_bytes # We use a shortened form just for visual clarity: 257 | self.b000_b431_timing_windows = self.unp(raw, "f"*108, 0, 431) 258 | self.b432_b435_has_branches = self.unp(raw, "i", 432, 435) 259 | self.b436_b439_hp_max = self.unp(raw, "i", 436, 439) 260 | self.b440_b443_hp_clear = self.unp(raw, "i", 440, 443) 261 | self.b444_b447_hp_gain_good = self.unp(raw, "i", 444, 447) 262 | self.b448_b451_hp_gain_ok = self.unp(raw, "i", 448, 451) 263 | self.b452_b455_hp_loss_bad = self.unp(raw, "i", 452, 455) 264 | self.b456_b459_normal_normal_ratio = self.unp(raw, "i", 456, 459) 265 | self.b460_b463_normal_professional_ratio = self.unp(raw, "i", 460, 463) 266 | self.b464_b467_normal_master_ratio = self.unp(raw, "i", 464, 467) 267 | self.b468_b471_branch_pts_good = self.unp(raw, "i", 468, 471) 268 | self.b472_b475_branch_pts_ok = self.unp(raw, "i", 472, 475) 269 | self.b476_b479_branch_pts_bad = self.unp(raw, "i", 476, 479) 270 | self.b480_b483_branch_pts_drumroll = self.unp(raw, "i", 480, 483) 271 | self.b484_b487_branch_pts_good_big = self.unp(raw, "i", 484, 487) 272 | self.b488_b491_branch_pts_ok_big = self.unp(raw, "i", 488, 491) 273 | self.b492_b495_branch_pts_drumroll_big = self.unp(raw, "i", 492, 495) 274 | self.b496_b499_branch_pts_balloon = self.unp(raw, "i", 496, 499) 275 | self.b500_b503_branch_pts_kusudama = self.unp(raw, "i", 500, 503) 276 | self.b504_b507_branch_pts_unknown = self.unp(raw, "i", 504, 507) 277 | self.b508_b511_dummy_data = self.unp(raw, "i", 508, 511) 278 | self.b512_b515_number_of_measures = self.unp(raw, "i", 512, 515) 279 | self.b516_b519_unknown_data = self.unp(raw, "i", 516, 519) 280 | 281 | def unp(self, raw_bytes: bytes, fmt: str, start: int, end: int) -> Any: 282 | """Unpack a raw byte string according to specific types.""" 283 | vals = struct.unpack(self.order + fmt, raw_bytes[start:end+1]) 284 | return vals[0] if len(vals) == 1 else vals 285 | 286 | def _parse_order(self, raw_bytes: bytes) -> None: 287 | """Parse the order of the song (little or big endian).""" 288 | self.order = '' 289 | # Bytes 512-515 are the number of measures. We check the values using 290 | # both little and big endian, then compare to see which is correct. 291 | if (self.unp(raw_bytes, ">I", 512, 515) < 292 | self.unp(raw_bytes, " None: 298 | """Set the timing window header bytes depending on the difficulty.""" 299 | # Note: Ura Oni is equivalent to Oni for timing window behavior 300 | difficulty = 'Oni' if difficulty in ['Ura', 'Edit'] else difficulty 301 | self.b000_b431_timing_windows = TIMING_WINDOWS[difficulty]*36 302 | 303 | def set_hp_bytes(self, n_notes: int, difficulty: str, stars: int) -> None: 304 | """Compute header bytes related to the soul gauge (HP) behavior.""" 305 | # Note: Ura Oni is equivalent to Oni for soul gauge behavior 306 | difficulty = 'Oni' if difficulty in ['Ura', 'Edit'] else difficulty 307 | self._get_hp_from_lookup_tables(n_notes, difficulty, stars) 308 | self.b440_b443_hp_clear = {'Easy': 6000, 'Normal': 7000, 309 | 'Hard': 7000, 'Oni': 8000}[difficulty] 310 | 311 | def _get_hp_from_lookup_tables(self, n_notes: int, difficulty: str, 312 | stars: int) -> None: 313 | """Fetch pre-computed soul gauge values from lookup tables (LUTs).""" 314 | if not 0 < n_notes <= 2500: 315 | return 316 | star_to_key = { 317 | 'Oni': {1: '17', 2: '17', 3: '17', 4: '17', 5: '17', 318 | 6: '17', 7: '17', 8: '8', 9: '910', 10: '910'}, 319 | 'Hard': {1: '12', 2: '12', 3: '3', 4: '4', 5: '58', 320 | 6: '58', 7: '58', 8: '58', 9: '58', 10: '58'}, 321 | 'Normal': {1: '12', 2: '12', 3: '3', 4: '4', 5: '57', 322 | 6: '57', 7: '57', 8: '57', 9: '57', 10: '57'}, 323 | 'Easy': {1: '1', 2: '23', 3: '23', 4: '45', 5: '45', 324 | 6: '45', 7: '45', 8: '45', 9: '45', 10: '45'}, 325 | } 326 | key = f"{difficulty}-{star_to_key[difficulty][stars]}" 327 | pkg_dir = os.path.dirname(os.path.realpath(__file__)) 328 | with open(os.path.join(pkg_dir, "hp_values.csv"), 329 | newline='', encoding="utf-8") as csv_file: 330 | for num, line in enumerate(csv.DictReader(csv_file)): 331 | if num+1 == n_notes: 332 | self.b444_b447_hp_gain_good = int(line[f"good_{key}"]) 333 | self.b448_b451_hp_gain_ok = int(line[f"ok_{key}"]) 334 | self.b452_b455_hp_loss_bad = int(line[f"bad_{key}"]) 335 | break 336 | 337 | @property 338 | def raw_bytes(self) -> bytes: 339 | """Represent the header values as a string of raw bytes.""" 340 | format_string, value_list = '', [] 341 | for byte_field in fields(self): 342 | value = getattr(self, byte_field.name) 343 | if byte_field.name == "order": 344 | format_string = value + format_string 345 | elif byte_field.name == "b000_b431_timing_windows": 346 | format_string += "f" * len(value) 347 | value_list.extend(list(value)) 348 | else: 349 | format_string += "i" 350 | value_list.append(value) 351 | raw_bytes = struct.pack(format_string, *value_list) 352 | assert len(raw_bytes) == 520 353 | return raw_bytes 354 | 355 | 356 | @dataclass() 357 | class FumenCourse: 358 | """Contains all the data in a single Fumen (`.bin`) chart file.""" 359 | header: FumenHeader 360 | measures: List[FumenMeasure] = field(default_factory=list) 361 | score_init: int = 0 362 | score_diff: int = 0 363 | -------------------------------------------------------------------------------- /testing/data/hol6po.tja: -------------------------------------------------------------------------------- 1 | BPM:90 2 | OFFSET:-2.749 3 | 4 | COURSE:Edit 5 | LEVEL:10 6 | BALLOON:13,4,52,4,52,4,52 7 | SCOREINIT:300 8 | SCOREDIFF:67 9 | 10 | #START 11 | 100020002000100000100100100020002000100020002000, 12 | 1000001110221202, 13 | #BPMCHANGE 80 14 | #SCROLL 1.13 15 | #BARLINEOFF 16 | 500008 17 | #BPMCHANGE 102.5 18 | #SCROLL 0.58 19 | 100000, 20 | #BPMCHANGE 205 21 | #SCROLL 1 22 | 7000000000008011, 23 | #BRANCHSTART p,86,94 24 | #N 25 | #BARLINEON 26 | 10111111, 27 | 111110 28 | #GOGOSTART 29 | 30 | #SCROLL 1.40 31 | 40, 32 | #SCROLL 1 33 | 1000112000112010, 34 | 1000112000112010, 35 | 1000112000112010, 36 | 1000112000111011, 37 | 1000211000112010, 38 | 1000211000112010, 39 | 1000211000101110, 40 | #GOGOEND 41 | 2, 42 | 10220210, 43 | 1020201000222000, 44 | 45 | #E 46 | #BARLINEON 47 | 100000000000100000100000100000100000100000100100, 48 | 100000100000100000100000100000000000 49 | #GOGOSTART 50 | 51 | #SCROLL 2.05 52 | 400000000000, 53 | #SCROLL 1 54 | 100000000000100100200000000000100100200000100100, 55 | 100000000000100100200000000000100100200100100000, 56 | 100000000000100100200000000000100100200000100100, 57 | 100000000000100100200000000000100100100200100100, 58 | 100000000000200100100000000000100100200000100100, 59 | 100000000000200100100000000000100100200100100000, 60 | 100000000000200100100000000000100000100100100100, 61 | #GOGOEND 62 | 200000000000200000200200200000100000200000000000, 63 | 100000000000200000200000000000200000100000000000, 64 | 100000200000200000100000000000200200200000000000, 65 | 66 | #M 67 | #BARLINEON 68 | 100000000000100000100000100000100000100000100100, 69 | 100100100100100100100100100000000000 70 | #GOGOSTART 71 | 72 | #SCROLL 2.7 73 | 400000000000, 74 | #SCROLL 1 75 | 100000000200100100200000000200100100200000100100, 76 | 100000000200100100200000000200100100200100100000, 77 | 100000000200100100200000000200100100200000100100, 78 | 100000000200100100200000000200100100100200100100, 79 | 100000000100200100100000000100100100200000100100, 80 | 100000000100200100100000000100100100200100100000, 81 | 100000000100200100100000100100100200100100100100, 82 | #GOGOEND 83 | 200000000000200200200200200000100000200000000000, 84 | 100000000000200200200000000000200000100000000000, 85 | 100000200000200000100000000000200200200000000000, 86 | 87 | #SECTION 88 | #BRANCHSTART p,86,94 89 | 90 | #N 91 | 1000102000101022, 92 | 2010222000101000, 93 | 10220210, 94 | 12210220, 95 | 2222201000201020, 96 | 2022201000101000, 97 | 10220210, 98 | 12210222, 99 | 10210230, 100 | 2010222000101000, 101 | 10120121, 102 | 1020112000104000, 103 | 104 | #E 105 | 100000000000100000200200200000100000100000200200, 106 | 200000100000200200200000000000100000100000000000, 107 | 100000000000200000200000000000200000100000000000, 108 | 100000200000200000100200200000200000200000000000, 109 | 200200200200200000100000000000200000100000200000, 110 | 200000100200200000100000000000100000100000000000, 111 | 100000000000200200200000000000200000100000000000, 112 | 100100200000200000100000000000200000200000200000, 113 | 100000000000200000100200200000200000300000000000, 114 | 200000100000200200200000000000100000100000200200, 115 | 100000000000100100200000000000100000200000100200, 116 | 100000200000100100200000000000100000400000000000, 117 | 118 | #M 119 | 100000000000100000200200200000100000100000200200, 120 | 200000100000202020200000000000100000100000000000, 121 | 100000000000200200200000000000200000100000000000, 122 | 100000200000200000100200200000200000200000000000, 123 | 200200200200200000100000000000200000100000200000, 124 | 200000102020200000100000000000100000100000000000, 125 | 100000000000200200200000000000200000100000000000, 126 | 100100200000200000100000000000200000200000200000, 127 | 100000000000200000100200200000200000300000000000, 128 | 200000100000202020200000000000100000100000200200, 129 | 100000000000100100200000000000100000200000100200, 130 | 100000200000100100200000000000100000400000000000, 131 | 132 | #SECTION 133 | #BRANCHSTART p,86,94 134 | 135 | #N 136 | 2220111020102010, 137 | 1010201120104000, 138 | 1002101000111020, 139 | 11010110, 140 | 1002101000222010, 141 | 11030110, 142 | 1002101000111020, 143 | 11010120, 144 | 1002102000101002, 145 | 12011440, 146 | 1002101000111020, 147 | 11010110, 148 | 1002102000111020, 149 | 11030110, 150 | 1002101000111020, 151 | 11010170, 152 | 8020102011102000, 153 | 154 | #E 155 | 200200200200100100100100200200100000200000100200, 156 | 100000100200200000100100200000100000400000000000, 157 | 100000000200100000100000000000100200100000200000, 158 | 100200100000000000100000000000100000100000200200, 159 | 100000000200100000100000000000200200200000100000, 160 | 100200100000200000300000000000100000100000200200, 161 | 100000000200100000100000000000100200100000200000, 162 | 100200100000000000100000000000100000100000200100, 163 | 100000000200100000200000000000100000100000000200, 164 | 100000200000000000100200100000400000400000000000, 165 | 100000000200100000100000000000100200100000200000, 166 | 100200100000000000100000000000100000100000200200, 167 | 100000000200100000200000000000100100100000200000, 168 | 100200100000200000300000000000100000100000200200, 169 | 100000000200100000100000000000100200100000200000, 170 | 100200100000000000100000200200100000700000000000, 171 | 8020102011102000, 172 | 173 | #M 174 | 200200200200100100100100200200100100200200100200, 175 | 100000100200200000100100200000100000400000000000, 176 | 100000000200100000100000200200100200100000200000, 177 | 100200100200000200100000000200100000100000200200, 178 | 100000000200100000100000200200200200200000100000, 179 | 100200100100200000300000000000100000100000200200, 180 | 100000000200100000100000200200100200100000200000, 181 | 100200100200000200100000000200100000100000200100, 182 | 100000000200100000200000000100100000100000000200, 183 | 100000200000200100100200100000400000400000000000, 184 | 100000000200100000100000200200100200100000200000, 185 | 100200100200000200100000000200100000100000200200, 186 | 100000000200100000200000100100100100100000200000, 187 | 100200100100200000300000000000100000100000200200, 188 | 100000000200100000100000200200100200100000200200, 189 | 100200100200000200100000200200100000700000000000, 190 | 8020102011102000, 191 | 192 | #SECTION 193 | #BRANCHSTART p,86,94 194 | 195 | #N 196 | 2011102000201000, 197 | 20020020, 198 | 0001, 199 | 10210210, 200 | 0001, 201 | 20020020, 202 | 0001, 203 | 10210210, 204 | 0001, 205 | 1022200020222000, 206 | 2022202020222000, 207 | 2022200020222000, 208 | 2022202010111000, 209 | 10121112, 210 | 1010101110104000, 211 | 212 | #E 213 | 200000100100100000200000100000200000100000000000, 214 | 200000000000000000200000000000000000200000000000, 215 | 000000200000000000200000000000000000100000000000, 216 | 100000000000200000100000000000200000100000000000, 217 | 000000100000000000100000000000000000100000000000, 218 | 200000000000000000200000000000000000200000000000, 219 | 000000200000000000200000000000000000100000000000, 220 | 100000000000200000100000000000200000100000000000, 221 | 000000100000000000100000000000000000100000000000, 222 | 100000200200200000200200200000200200200000200200, 223 | 200000200200200000200200200000200200200000200200, 224 | 200000200200200000200200200000200200200000200200, 225 | 200000200200200000200200100000100100100000200200, 226 | 100000000000100000200200100000100000100000200200, 227 | 100000100000100000100100100000100000400000000000, 228 | 229 | #M 230 | 200200100100100100200200100100200200100100100100, 231 | 200000000000200000200000000000200200200000000000, 232 | 200000200000000000200000000000200000100000000000, 233 | 100000000000200000100000000000200200100000000000, 234 | 200000100000000000100000000000200000100000200200, 235 | 200000000000200000200000000000200200200000000000, 236 | 200000200000000000200000000000200000100000000000, 237 | 100000000000200000100000000000200200100000000000, 238 | 200000100000000000100000000000200200100000202020, 239 | 100000200200200000200200200000200200200000202020, 240 | 200000200200200000200200200000200200200000202020, 241 | 200000200200200000200200200000200200200000202020, 242 | 200000200200200000200200100000100100100000202020, 243 | 100000000000100000200200100000100000100000202020, 244 | 100000100000100000100100100000100000400000000000, 245 | 246 | #SECTION 247 | #BRANCHSTART p,86,94 248 | 249 | #N 250 | 11212014, 251 | 0011201020100040, 252 | 000100200100500000008000, 253 | #GOGOSTART 254 | 30201120, 255 | 1110200011102000, 256 | 10201120, 257 | 1210200012102000, 258 | 10201120, 259 | 1110200011102000, 260 | 10201120, 261 | 1210200010404000, 262 | 10201120, 263 | 1110200011102000, 264 | 10201120, 265 | 1210200012102000, 266 | 10201120, 267 | 2210200011102000, 268 | 1000200012102000, 269 | 1210201010201000, 270 | #GOGOEND 271 | 11201201, 272 | 273 | #E 274 | 100000100000200000100100200000000000100000400000, 275 | 000000100100200000100100200200100000000000400000, 276 | 000000100100200200100000500000000000000080000000, 277 | #GOGOSTART 278 | 300000000000200000100000100000100000200000100000, 279 | 100100100000200000100000100100100000200000100000, 280 | 100000000000200000200000100000100000200000200000, 281 | 100200100000200000200000100200100000200000200000, 282 | 100000000000200000100000100000100000200000100000, 283 | 100100100000200000100000100100100000200000100000, 284 | 100000000000200000200000100000100000200000200000, 285 | 100200100000200000100200100000400000400000000000, 286 | 100000000000200000100000100000100000200000100000, 287 | 100100100000200000100000100100100000200000100000, 288 | 100000000000200000200000100000100000200000200000, 289 | 100200100000200000200000100200100000200000200000, 290 | 100000000000200000100000100000100000200000100000, 291 | 200200100000200000100000100100100000200000100000, 292 | 100000100000200000200000100200100000200000200000, 293 | 100200100000200000100200100000200000100000000000, 294 | #GOGOEND 295 | 100000100000200000000000100000200000000000100000, 296 | 297 | #M 298 | 100000100000200000100100200000000000100000400000, 299 | 000000100100200000101010200200100100100000400000, 300 | 000000101010200200100000500000000000000080000000, 301 | #GOGOSTART 302 | 300000000000200000100100100000100000200000100000, 303 | 100100100000200000100000100100100000200000100100, 304 | 100000000000200000200200100000100000200000200200, 305 | 100200100000200000200200100200100000200000200200, 306 | 100000000000200000100100100000100000200000100000, 307 | 100100100000200000100000100100100000200000100100, 308 | 100000000000200000200200100000100000200000200200, 309 | 100200100000200200100200100000400000400000000000, 310 | 100000000000200000100100100000100000200000100100, 311 | 100100100000200000100100100100100000200000100100, 312 | 100000000000200000200200100000100000200000200200, 313 | 100200100000200000200200100200100000200000200200, 314 | 100000000000200000100100100000100000200000100100, 315 | 200200100000200000100100100100100000200000100100, 316 | 100000100000200000200200100200100000200000200200, 317 | 100200100000200200100200100100200200100100100000, 318 | #GOGOEND 319 | 100000100000200000000000100000200000000000100000, 320 | 321 | #SECTION 322 | #BRANCHSTART p,86,94 323 | 324 | #N 325 | 20211000, 326 | 1000200011011000, 327 | 1000200011011000, 328 | 10101110, 329 | 1011101010101000, 330 | 10101110, 331 | 1011101010004000, 332 | 30210120, 333 | 10210120, 334 | 1000201000112000, 335 | 1000201000112000, 336 | 1002101000112000, 337 | 1002101000112000, 338 | 1012100010121000, 339 | 3030302211112020, 340 | 341 | #E 342 | 200000000000200000100000100100100000200000200200, 343 | 100000000000200000100000100100000100200000100000, 344 | 100000200000100000200000100100000100100000100000, 345 | 100000000000200000000000100000100000200000000000, 346 | 100000100100200000100000200000100000100100200000, 347 | 200000000000100000000000200000200000100000200000, 348 | 100000200000100100200100100000100000200000000000, 349 | 300000000100200000100000000000100000200000100000, 350 | 100000000100200000100000000000100000200000100000, 351 | 100000000100200000100000000000100100200000100000, 352 | 100000000100200000100000000000100100200000100000, 353 | 100000000200100000100000000000100100200000100000, 354 | 100000000200100000100000000000100100200000100000, 355 | 100000100200100000200000100000100200100000200000, 356 | 300000300000300000200200100100100100200000200000, 357 | 358 | #M 359 | 200000000000200000100000100100100000200000200200, 360 | 100000000000200000100000100100000100200000100000, 361 | 100000200000100000200000100100000100100000100000, 362 | 100000000000200000000000100000100000200000100000, 363 | 200000100000200000100000100100100000200000100000, 364 | 200000200200100000200000200000100000200000100000, 365 | 100000100200200200100200100000400000300000400000, 366 | 300000000100200000100000000200100000200000100000, 367 | 100000000100200000100000000200100000200000100200, 368 | 100000000100200000100000000200100100200000100000, 369 | 100000000100200000100000000200100100200000100200, 370 | 100000000200100000100200000200100100200000100000, 371 | 100000000200100000100200000200100100200000100200, 372 | 100000100200100000200100100000100200100100200000, 373 | 300000300000300000200200100100100100200000200000, 374 | 375 | #SECTION 376 | #BRANCHSTART p,86,94 377 | 378 | #N 379 | #GOGOSTART 380 | 3000111020101000, 381 | 1110201020101000, 382 | 1000111020101000, 383 | 1210201020101000, 384 | 1000111020101000, 385 | 1110201020101000, 386 | 1000111020101000, 387 | 1120100010404000, 388 | 1000111020101020, 389 | 1110201020101000, 390 | 1000111020101020, 391 | 1210201020101000, 392 | 1000111020101010, 393 | 2210201020101000, 394 | 10212121, 395 | 2220222022111000, 396 | #GOGOEND 397 | 3333, 398 | 30303011, 399 | 4444, 400 | 40404022, 401 | 3000102210001021, 402 | 100000100100100000100100100000004000000030000000, 403 | 4, 404 | , 405 | 406 | #E 407 | #GOGOSTART 408 | 300000000000100100100000200000100000100000200000, 409 | 100100100000200000100000200000100000100100200000, 410 | 100000000000100100100000200000100000100000200000, 411 | 100200100000200000100000200000100000100100200000, 412 | 100000000000100100100000200000100000100000200000, 413 | 100100100000200000100000200000100000100100200000, 414 | 100000000000100200100000200000100200100000200000, 415 | 100100200000100000200000100000400000400000000000, 416 | 100000000000100100100000200000100000100000200000, 417 | 100100100000200000100000200000100000100100200000, 418 | 100000000000100100100000200000100000100000200000, 419 | 100200100100200000100000200000100000100100200000, 420 | 100000000000100100100000200000100000100000100000, 421 | 200200100000200000100000200000100000100100200000, 422 | 100000100000200000100000200200100000200000100000, 423 | 200200200200200200200200200200100100100000000000, 424 | #GOGOEND 425 | 300000200000300000000000300000200000300000200000, 426 | 300000200000300000200000300000000000100000100000, 427 | 400000100000400000000000400000100000400000100000, 428 | 400000100000400000100000400000000000200000200000, 429 | 300000200200100000200200100000200100100000200100, 430 | 100000100100100000100100100000004000000030000000, 431 | 400000000000000000000000000000000000000000000000, 432 | 000000000000000000000000000000000000000000000000, 433 | 434 | #M 435 | #GOGOSTART 436 | 300000000000100100100000200000100100100000200000, 437 | 100100100000200200100000200000100000100100200200, 438 | 100000200000100100100000200000100200100000200000, 439 | 100200100000200200100000200000100000100100200200, 440 | 100000200000100100100000200000100100100000200000, 441 | 100100100000200200100000200000100000100100200200, 442 | 100000200000100200100000200000100200100000200000, 443 | 100100200000100100200000100000400000400000000000, 444 | 100000200000100100100000200000100100100000200000, 445 | 100100100000200200100100200000100100100100200200, 446 | 100000200000100100100000200000100200100000200000, 447 | 100200100100200200100100200000100200100100200200, 448 | 100000200000100100100000200000100100100000100000, 449 | 200200100000200200100100200000100100100100200200, 450 | 100000100000200200100000200200100100200000100000, 451 | 200200200200200200200200202020100100100100100000, 452 | #GOGOEND 453 | 300000200000300000000000300000200000300000200000, 454 | 300000200000300000200000300000000000100200100000, 455 | 400000100000400000000000400000100000400000100000, 456 | 400000100000400000100000400000000000200100200000, 457 | 300000200200100200200200100200200100100200200100, 458 | 100200100100100200100100100000004000000030000000, 459 | 400000000000000000000000000000000000000000000000, 460 | 000000000000000000000000000000000000000000000000, 461 | 462 | #SECTION 463 | #BRANCHSTART p,86,94 464 | 465 | #N 466 | #GOGOSTART 467 | 1000112000112010, 468 | 1000112000112010, 469 | 1000112000112010, 470 | 1000112000111011, 471 | #GOGOEND 472 | 7, 473 | #BARLINEOFF 474 | , 475 | 0000000000000008, 476 | #MEASURE 1/4 477 | #SCROLL 1.4 478 | 0111, 479 | #MEASURE 4/4 480 | 2, 481 | 482 | #E 483 | #GOGOSTART 484 | 100000000000100100200000000000100100200000100100, 485 | 100000000000100100200000000000100100200100100000, 486 | 100000000000100100200000000000100100200000100100, 487 | 100000000000100100200000000000100100100200100100, 488 | #GOGOEND 489 | 7, 490 | #BARLINEOFF 491 | , 492 | 0000000000000008, 493 | #MEASURE 1/4 494 | #SCROLL 2.05 495 | 0112, 496 | #MEASURE 4/4 497 | 1, 498 | 499 | #M 500 | #GOGOSTART 501 | 100000000200100100200000000200100100200000100100, 502 | 100000000200100100200000000200100100200100100000, 503 | 100000000200100100200000000200100100200000100100, 504 | 100000000200101010200200200200100100100200100100, 505 | #GOGOEND 506 | 7, 507 | #BARLINEOFF 508 | , 509 | 0000000000000008, 510 | #MEASURE 1/4 511 | #SCROLL 2.7 512 | 0121, 513 | #MEASURE 4/4 514 | 1, 515 | 516 | #BRANCHEND 517 | 518 | #END 519 | 520 | COURSE:Oni 521 | LEVEL:6 522 | BALLOON:7,13,7,4,4,21,4,4,2,35 523 | SCOREINIT:520 524 | SCOREDIFF:122 525 | 526 | #START 527 | 1202, 528 | 1000201110000000, 529 | #BARLINEOFF 530 | #BPMCHANGE 80 531 | #SCROLL 1.13 532 | 00 533 | #BPMCHANGE 102.5 534 | #SCROLL 2 535 | 00, 536 | #BPMCHANGE 205 537 | #SCROLL 2.05 538 | 7008, 539 | #BARLINEON 540 | #SCROLL 1 541 | 30111111, 542 | 111110 543 | #GOGOSTART 544 | 40, 545 | 30030030, 546 | 30030030, 547 | 30030030, 548 | 3000003000111000, 549 | 1000101000111000, 550 | 1000101000111000, 551 | 1000101000111000, 552 | #GOGOEND 553 | 3, 554 | 10110020, 555 | , 556 | 10110000, 557 | , 558 | 10110020, 559 | , 560 | 20220010, 561 | , 562 | 10110020, 563 | , 564 | 10110030, 565 | , 566 | 10110110, 567 | 11010070, 568 | 00000008, 569 | 2223, 570 | 10110110, 571 | 11010000, 572 | 10110110, 573 | 11020000, 574 | 10110110, 575 | 11010000, 576 | 10110110, 577 | 11020330, 578 | 10110110, 579 | 11010220, 580 | 10110110, 581 | 11020110, 582 | 40110110, 583 | 11010440, 584 | 01022010, 585 | 22010220, 586 | 5, 587 | 0800, 588 | 20020020, 589 | , 590 | 5, 591 | 0800, 592 | 10010070, 593 | 00080000, 594 | 1222, 595 | 1222, 596 | 1222, 597 | 1000200020222000, 598 | 10101110, 599 | 11111030, 600 | 10202003, 601 | 0011100020200030, 602 | 01107008, 603 | #GOGOSTART 604 | 10201120, 605 | 10201120, 606 | 10201120, 607 | 11201120, 608 | 10201120, 609 | 10201120, 610 | 11101110, 611 | 1110100010101000, 612 | 10201120, 613 | 10201120, 614 | 10201120, 615 | 11201120, 616 | 10201120, 617 | 10201120, 618 | 11201120, 619 | 1110200070000080, 620 | #GOGOEND 621 | 10201001, 622 | 0110, 623 | 1000200011011000, 624 | 1000200011011000, 625 | 10101110, 626 | 1011101010002000, 627 | 7, 628 | 00000008, 629 | 10210120, 630 | 10210120, 631 | 10210120, 632 | 10210120, 633 | 20210120, 634 | 20210120, 635 | 11102220, 636 | 33307008, 637 | #GOGOSTART 638 | 10201120, 639 | 11201120, 640 | 10201120, 641 | 11211120, 642 | 10201120, 643 | 11201120, 644 | 11101110, 645 | 1110100010101000, 646 | 10201120, 647 | 11201120, 648 | 10201120, 649 | 11211120, 650 | 10201120, 651 | 11201120, 652 | 11201120, 653 | 1110200070000080, 654 | #GOGOEND 655 | 3333, 656 | 30303011, 657 | 4444, 658 | 40404022, 659 | 1111, 660 | 100100303030, 661 | 70800000, 662 | , 663 | #GOGOSTART 664 | 1000101000111000, 665 | 1000101000111000, 666 | 1000101000111000, 667 | 1000101000111000, 668 | #GOGOEND 669 | #BARLINEON 670 | 7, 671 | #BARLINEOFF 672 | , 673 | 0000000000000008, 674 | #MEASURE 1/4 675 | 0221, 676 | #MEASURE 4/4 677 | 1, 678 | , 679 | , 680 | , 681 | , 682 | , 683 | , 684 | , 685 | , 686 | , 687 | , 688 | #END 689 | 690 | COURSE:Hard 691 | LEVEL:3 692 | BALLOON:30,14,9,16,18,18,18,18 693 | SCOREINIT:570 694 | SCOREDIFF:140 695 | 696 | #START 697 | 1202, 698 | 10211000, 699 | #BARLINEOFF 700 | #BPMCHANGE 80 701 | #SCROLL 1.13 702 | 00 703 | #BPMCHANGE 102.5 704 | #SCROLL 2 705 | 00, 706 | #BPMCHANGE 205 707 | #SCROLL 1.5 708 | 7, 709 | #BARLINEON 710 | #SCROLL 1 711 | 0, 712 | 000000000000 713 | #GOGOSTART 714 | 8000, 715 | 30030030, 716 | 30030030, 717 | 30030030, 718 | 30030030, 719 | 10110110, 720 | 10110110, 721 | 10110110, 722 | #GOGOEND 723 | 3, 724 | 1, 725 | , 726 | 10010000, 727 | , 728 | 1, 729 | , 730 | 20020000, 731 | , 732 | 1, 733 | , 734 | 10010030, 735 | , 736 | 2, 737 | 10010070, 738 | , 739 | 8, 740 | 10010010, 741 | 01010000, 742 | 10010010, 743 | 01010000, 744 | 10010010, 745 | 01010000, 746 | 10010010, 747 | 02020000, 748 | 10010010, 749 | 01010000, 750 | 10010010, 751 | 01010000, 752 | 4, 753 | 10010010, 754 | 01010000, 755 | 7008, 756 | 5, 757 | 000008000000000000000000, 758 | 20020020, 759 | , 760 | 5, 761 | 000008000000000000000000, 762 | 10010010, 763 | , 764 | 2220, 765 | 2, 766 | 2220, 767 | 2, 768 | 1110, 769 | 11101000, 770 | 9, 771 | , 772 | 8, 773 | #GOGOSTART 774 | 10101110, 775 | 1110, 776 | 10101110, 777 | 1120, 778 | 10101110, 779 | 1110, 780 | 10101110, 781 | 2220, 782 | 10101110, 783 | 1110, 784 | 10101110, 785 | 1120, 786 | 10101110, 787 | 1110, 788 | 7, 789 | 000000000080, 790 | #GOGOEND 791 | 10201001, 792 | 0110, 793 | 1212, 794 | 1010, 795 | 30101110, 796 | 30101110, 797 | 7, 798 | 000000000080, 799 | 10010020, 800 | 10010020, 801 | 10010020, 802 | 10010000, 803 | 20010010, 804 | 20010010, 805 | 2010, 806 | 3300, 807 | #GOGOSTART 808 | 10101110, 809 | 10101110, 810 | 10101110, 811 | 1120, 812 | 10101110, 813 | 10101110, 814 | 10101110, 815 | 2220, 816 | 10101110, 817 | 10101110, 818 | 10101110, 819 | 1120, 820 | 10101110, 821 | 10101110, 822 | 7, 823 | 000000000080, 824 | #GOGOEND 825 | 3333, 826 | 3330, 827 | 4444, 828 | 4440, 829 | 9, 830 | , 831 | 000080000000, 832 | , 833 | #GOGOSTART 834 | 10110110, 835 | 10110110, 836 | 10110110, 837 | 10110110, 838 | #GOGOEND 839 | 3, 840 | #BARLINEOFF 841 | , 842 | , 843 | #MEASURE 1/4 844 | , 845 | #MEASURE 4/4 846 | 0, 847 | , 848 | , 849 | , 850 | , 851 | , 852 | , 853 | , 854 | , 855 | , 856 | , 857 | #END 858 | 859 | COURSE:Normal 860 | LEVEL:2 861 | BALLOON:18,8,8,12,11,11,11,14 862 | SCOREINIT:640 863 | SCOREDIFF:195 864 | 865 | #START 866 | 1, 867 | 1010, 868 | #BARLINEOFF 869 | #BPMCHANGE 80 870 | #SCROLL 1.13 871 | 00 872 | #BPMCHANGE 102.5 873 | #SCROLL 2 874 | 00, 875 | #BPMCHANGE 205 876 | #SCROLL 1 877 | 7, 878 | #BARLINEON 879 | 0, 880 | 000000000008 881 | #GOGOSTART 882 | 0000, 883 | 30030000, 884 | 30030000, 885 | 30030000, 886 | 30030000, 887 | 30030000, 888 | 30030000, 889 | 30030000, 890 | #GOGOEND 891 | 3, 892 | 1, 893 | , 894 | 1, 895 | , 896 | 1, 897 | , 898 | 2, 899 | , 900 | 1, 901 | , 902 | 1003, 903 | , 904 | 2, 905 | 1007, 906 | , 907 | 8, 908 | 10010000, 909 | , 910 | 10010000, 911 | , 912 | 10010000, 913 | , 914 | 20020000, 915 | , 916 | 10010000, 917 | , 918 | 10010030, 919 | , 920 | 4, 921 | 10010070, 922 | , 923 | 8, 924 | 5, 925 | 000008000000000000000000, 926 | 20020020, 927 | , 928 | 5, 929 | 000008000000000000000000, 930 | 10010010, 931 | , 932 | 2020, 933 | 2, 934 | 2020, 935 | 2, 936 | 1100, 937 | 1100, 938 | 9, 939 | , 940 | 8, 941 | #GOGOSTART 942 | 1010, 943 | 1110, 944 | 1010, 945 | 1110, 946 | 1010, 947 | 1110, 948 | 2020, 949 | 2, 950 | 1010, 951 | 1110, 952 | 1010, 953 | 1110, 954 | 1010, 955 | 1110, 956 | 7, 957 | 000000000080, 958 | #GOGOEND 959 | 1020, 960 | 1, 961 | 1020, 962 | 1, 963 | 1020, 964 | 1, 965 | 7, 966 | 000000000080, 967 | 10010010, 968 | 1, 969 | 10010010, 970 | 1, 971 | 10010010, 972 | 1, 973 | 1010, 974 | 3300, 975 | #GOGOSTART 976 | 1010, 977 | 1110, 978 | 1010, 979 | 1110, 980 | 1010, 981 | 1110, 982 | 2020, 983 | 2220, 984 | 1010, 985 | 1110, 986 | 1010, 987 | 1110, 988 | 1010, 989 | 1110, 990 | 7, 991 | 000000000080, 992 | #GOGOEND 993 | 3030, 994 | 3330, 995 | 4040, 996 | 4440, 997 | 9, 998 | , 999 | 000080000000, 1000 | , 1001 | #GOGOSTART 1002 | 30030000, 1003 | 30030000, 1004 | 30030000, 1005 | 30030000, 1006 | #GOGOEND 1007 | #BARLINEON 1008 | 3, 1009 | #BARLINEOFF 1010 | , 1011 | , 1012 | #MEASURE 1/4 1013 | , 1014 | #MEASURE 4/4 1015 | 0, 1016 | , 1017 | , 1018 | , 1019 | , 1020 | , 1021 | , 1022 | , 1023 | , 1024 | , 1025 | , 1026 | #END 1027 | 1028 | COURSE:Easy 1029 | LEVEL:2 1030 | BALLOON:15,7,7,8,10,10,10,10,10,9 1031 | SCOREINIT:990 1032 | SCOREDIFF:330 1033 | 1034 | #START 1035 | 1, 1036 | 1, 1037 | #BARLINEOFF 1038 | #BPMCHANGE 80 1039 | #SCROLL 1.13 1040 | 00 1041 | #BPMCHANGE 102.5 1042 | #SCROLL 1.5 1043 | 00, 1044 | #BPMCHANGE 205 1045 | #SCROLL 1 1046 | 7, 1047 | #BARLINEON 1048 | 0, 1049 | 000000000008 1050 | #GOGOSTART 1051 | 0000, 1052 | 6, 1053 | , 1054 | 000000000000000000000008, 1055 | , 1056 | 6, 1057 | , 1058 | 000000000008000000000000, 1059 | #GOGOEND 1060 | 3, 1061 | 1, 1062 | , 1063 | 1, 1064 | , 1065 | 1, 1066 | , 1067 | 1, 1068 | , 1069 | 1, 1070 | , 1071 | 1003, 1072 | , 1073 | 1, 1074 | 1007, 1075 | , 1076 | 8, 1077 | 1, 1078 | , 1079 | 1, 1080 | , 1081 | 1, 1082 | , 1083 | 2, 1084 | , 1085 | 1, 1086 | , 1087 | 1001, 1088 | , 1089 | 4, 1090 | 1007, 1091 | , 1092 | 8, 1093 | 5, 1094 | 000008000000000000000000, 1095 | 2002, 1096 | , 1097 | 5, 1098 | 000008000000000000000000, 1099 | 1001, 1100 | , 1101 | 2020, 1102 | 2, 1103 | 2, 1104 | , 1105 | 1010, 1106 | 1, 1107 | 9, 1108 | , 1109 | 8, 1110 | #GOGOSTART 1111 | 1, 1112 | 1, 1113 | 1, 1114 | 1010, 1115 | 1, 1116 | 1010, 1117 | 7, 1118 | 000000000080, 1119 | 1, 1120 | 1, 1121 | 1, 1122 | 1010, 1123 | 1, 1124 | 1010, 1125 | 7, 1126 | 000000000080, 1127 | #GOGOEND 1128 | 1, 1129 | 2, 1130 | 1, 1131 | 2, 1132 | 1, 1133 | 2, 1134 | 7, 1135 | 000000000080, 1136 | 1, 1137 | 2, 1138 | 1, 1139 | 2, 1140 | 1, 1141 | 2, 1142 | 1010, 1143 | 3, 1144 | #GOGOSTART 1145 | 1, 1146 | 1, 1147 | 1, 1148 | 1010, 1149 | 1, 1150 | 1010, 1151 | 7, 1152 | 000000000080, 1153 | 1, 1154 | 1, 1155 | 1, 1156 | 1010, 1157 | 1, 1158 | 1010, 1159 | 7, 1160 | 000000000080, 1161 | #GOGOEND 1162 | 3030, 1163 | 3030, 1164 | 3030, 1165 | 3030, 1166 | 9, 1167 | , 1168 | 000080000000, 1169 | #GOGOSTART 1170 | 0, 1171 | 6, 1172 | , 1173 | 000000000000000000000008, 1174 | , 1175 | #GOGOEND 1176 | 3, 1177 | #BARLINEOFF 1178 | , 1179 | , 1180 | #MEASURE 1/4 1181 | , 1182 | #MEASURE 4/4 1183 | 0, 1184 | , 1185 | , 1186 | , 1187 | , 1188 | , 1189 | , 1190 | , 1191 | , 1192 | , 1193 | , 1194 | #END 1195 | -------------------------------------------------------------------------------- /testing/data/imcanz.tja: -------------------------------------------------------------------------------- 1 | BPM:198.17285 2 | OFFSET:-4.174 3 | 4 | COURSE:Oni 5 | LEVEL:7 6 | BALLOON:39,4 7 | SCOREINIT:560 8 | SCOREDIFF:137 9 | 10 | 11 | #START 12 | 13 | 14 | #SCROLL 0.98 15 | 3, 16 | #BPMCHANGE 201.0636 17 | #SCROLL 0.96 18 | 3, 19 | #BPMCHANGE 188.4617 20 | #SCROLL 1.03 21 | 3, 22 | #BPMCHANGE 194.6087 23 | #SCROLL 1 24 | 7, 25 | , 26 | , 27 | , 28 | 8, 29 | , 30 | #BPMCHANGE 195.0002 31 | 1022102010200020, 32 | 1022102010002000, 33 | 1022102010200020, 34 | 1022102010201110, 35 | 1022102010200020, 36 | 1022102010002000, 37 | 1022102010201120, 38 | 500000000000000000000000000000000008000000000000, 39 | 1221 40 | 41 | #GOGOSTART 42 | 4121, 43 | 44 | #GOGOEND 45 | 0121 46 | 47 | #GOGOSTART 48 | 4141, 49 | 50 | #GOGOEND 51 | 12212121, 52 | 53 | #GOGOSTART 54 | 41414141, 55 | 56 | #GOGOEND 57 | 1221 58 | 59 | #GOGOSTART 60 | 4121, 61 | 62 | #GOGOEND 63 | 0121 64 | 65 | #GOGOSTART 66 | 4141, 67 | 68 | #GOGOEND 69 | 12212121, 70 | 000000100000200000100000500000000000000008000000, 71 | 100000000000200000100000000000500000000008000000, 72 | 100000000000200000100000000000500008000000200000, 73 | 100000000000200000100000000000500000000008000000, 74 | 10212000, 75 | #BARLINEOFF 76 | 22, 77 | 20002022, 78 | #BARLINEON 79 | 22224343, 80 | 3022102010200020, 81 | 1022102010002000, 82 | 1022102010200020, 83 | 1022102011201110, 84 | 1022102010200020, 85 | 1022102011102000, 86 | 1022102010201120, 87 | 500000000000000000000000000000000008000000000000, 88 | 10012102, 89 | 01212002, 90 | 10102101, 91 | 01011021, 92 | 10012102, 93 | 0010201020002220, 94 | 5, 95 | , 96 | , 97 | 000000000000000000000000000000000000000000000008, 98 | , 99 | , 100 | 101 | #GOGOSTART 102 | #BRANCHSTART p,0,0 103 | #N 104 | 1020201000201020, 105 | 1022100040004000, 106 | 12212212, 107 | 1022100040004000, 108 | 1022201020102010, 109 | 0022201022102000, 110 | 33034043, 111 | 000000600000000000000000000000000000000008000000, 112 | 12210212, 113 | 1022100040004000, 114 | 1020201020221020, 115 | 1022100040004000, 116 | 1022201022102010, 117 | 0022201022102000, 118 | 34034043, 119 | 03307008, 120 | 33, 121 | 3033, 122 | #GOGOEND 123 | , 124 | 125 | #E 126 | 1020201000201020, 127 | 1022100040004000, 128 | 12212212, 129 | 1022100040004000, 130 | 1022201020102010, 131 | 0022201022102000, 132 | 33034043, 133 | 000000600000000000000000000000000000000008000000, 134 | 12210212, 135 | 1022100040004000, 136 | 1020201020221020, 137 | 1022100040004000, 138 | 1022201022102010, 139 | 0022201022102000, 140 | 34034043, 141 | 03307008, 142 | 33, 143 | 3033, 144 | #GOGOEND 145 | , 146 | 147 | #M 148 | 1020201000201020, 149 | 1022100040004000, 150 | 12212212, 151 | 1022100040004000, 152 | 1022201020102010, 153 | 0022201022102000, 154 | 33034043, 155 | 000000600000000000000000000000000000000008000000, 156 | 12210212, 157 | 1022100040004000, 158 | 1020201020221020, 159 | 1022100040004000, 160 | 1022201022102010, 161 | 0022201022102000, 162 | 34034043, 163 | 03307008, 164 | 33, 165 | 3033, 166 | #GOGOEND 167 | , 168 | 169 | #BRANCHSTART p,999,999 170 | #N 171 | , 172 | 600000000000000008000000100000200000100000200000, 173 | 600000000000000008000000100000200000100000200000, 174 | 1022102010201110, 175 | 1022102010221020, 176 | 3020102010201110, 177 | 3020102010201120, 178 | 3022102010201110, 179 | 3022102010201120, 180 | #SECTION 181 | 3111, 182 | 3111, 183 | 6, 184 | 000000000000000000000000000000000000000000000008, 185 | , 186 | , 187 | 188 | #E 189 | , 190 | 600000000000000008000000100000200000100000200000, 191 | 600000000000000008000000100000200000100000200000, 192 | 1022102010201110, 193 | 1022102010221020, 194 | 3020102010201110, 195 | 3020102010201120, 196 | 3022102010201110, 197 | 3022102010201120, 198 | #SECTION 199 | 3111, 200 | 3111, 201 | 6, 202 | 000000000000000000000000000000000000000000000008, 203 | , 204 | , 205 | 206 | #M 207 | , 208 | 600000000000000008000000100000200000100000200000, 209 | 600000000000000008000000100000200000100000200000, 210 | 1022102010201110, 211 | 1022102010221020, 212 | 3020102010201110, 213 | 3020102010201120, 214 | 3022102010201110, 215 | 3022102010201120, 216 | #SECTION 217 | 3111, 218 | 3111, 219 | 6, 220 | 000000000000000000000000000000000000000000000008, 221 | , 222 | , 223 | 224 | #BRANCHSTART r,0,1 225 | #N 226 | , 227 | #BARLINEOFF 228 | , 229 | , 230 | 0002, 231 | #BARLINEON 232 | #MEASURE 1/8 233 | #SCROLL 0.75 234 | , 235 | , 236 | , 237 | #MEASURE 1/4 238 | , 239 | #MEASURE 1/8 240 | , 241 | , 242 | #MEASURE 3/8 243 | , 244 | #MEASURE 1/4 245 | , 246 | #GOGOSTART 247 | , 248 | , 249 | #GOGOEND 250 | #MEASURE 1/8 251 | , 252 | , 253 | , 254 | #MEASURE 1/4 255 | , 256 | #MEASURE 1/8 257 | , 258 | , 259 | #MEASURE 1/4 260 | , 261 | #MEASURE 1/8 262 | , 263 | #MEASURE 1/4 264 | , 265 | #GOGOSTART 266 | , 267 | , 268 | , 269 | #MEASURE 1/8 270 | , 271 | , 272 | #MEASURE 1/4 273 | , 274 | #MEASURE 1/8 275 | , 276 | #MEASURE 1/4 277 | , 278 | , 279 | #MEASURE 1/8 280 | , 281 | #MEASURE 2/4 282 | , 283 | #MEASURE 1/8 284 | , 285 | #MEASURE 1/4 286 | , 287 | #MEASURE 1/8 288 | , 289 | #MEASURE 1/4 290 | , 291 | #GOGOSTART 292 | #MEASURE 5/4 293 | 0 294 | #GOGOEND 295 | 0000, 296 | 297 | #GOGOSTART 298 | #MEASURE 4/4 299 | #SCROLL 1 300 | 12210212, 301 | 1022100040004000, 302 | 12212212, 303 | 1022100040004000, 304 | 1022201020102010, 305 | 0022201022102000, 306 | 33034043, 307 | 03402020, 308 | 33, 309 | 3033, 310 | 311 | #GOGOEND 312 | , 313 | , 314 | 315 | #GOGOSTART 316 | 3, 317 | #BARLINEOFF 318 | , 319 | 320 | #GOGOEND 321 | , 322 | , 323 | #SCROLL 0.5 324 | 0002000000000000, 325 | 326 | #E 327 | , 328 | #BARLINEOFF 329 | , 330 | , 331 | 0002, 332 | #BARLINEON 333 | #MEASURE 1/8 334 | #SCROLL 0.75 335 | , 336 | , 337 | , 338 | #MEASURE 1/4 339 | , 340 | #MEASURE 1/8 341 | , 342 | , 343 | #MEASURE 3/8 344 | , 345 | #MEASURE 1/4 346 | , 347 | #GOGOSTART 348 | , 349 | , 350 | #GOGOEND 351 | #MEASURE 1/8 352 | , 353 | , 354 | , 355 | #MEASURE 1/4 356 | , 357 | #MEASURE 1/8 358 | , 359 | , 360 | #MEASURE 1/4 361 | , 362 | #MEASURE 1/8 363 | , 364 | #MEASURE 1/4 365 | , 366 | #GOGOSTART 367 | , 368 | , 369 | , 370 | #MEASURE 1/8 371 | , 372 | , 373 | #MEASURE 1/4 374 | , 375 | #MEASURE 1/8 376 | , 377 | #MEASURE 1/4 378 | , 379 | , 380 | #MEASURE 1/8 381 | , 382 | #MEASURE 2/4 383 | , 384 | #MEASURE 1/8 385 | , 386 | #MEASURE 1/4 387 | , 388 | #MEASURE 1/8 389 | , 390 | #MEASURE 1/4 391 | , 392 | #GOGOSTART 393 | #MEASURE 5/4 394 | 0 395 | #GOGOEND 396 | 0000, 397 | 398 | #GOGOSTART 399 | #MEASURE 4/4 400 | #SCROLL 1 401 | 12210212, 402 | 1022100040004000, 403 | 12212212, 404 | 1022100040004000, 405 | 1022201020102010, 406 | 0022201022102000, 407 | 33034043, 408 | 03402020, 409 | 33, 410 | 3033, 411 | 412 | #GOGOEND 413 | , 414 | , 415 | 416 | #GOGOSTART 417 | 3, 418 | #BARLINEOFF 419 | , 420 | 421 | #GOGOEND 422 | , 423 | , 424 | #SCROLL 0.5 425 | 0002000000000000, 426 | 427 | #M 428 | , 429 | #BARLINEOFF 430 | , 431 | , 432 | 0002, 433 | #BARLINEON 434 | #MEASURE 1/8 435 | #SCROLL 0.75 436 | 2, 437 | 2, 438 | 2, 439 | #MEASURE 1/4 440 | 2, 441 | #MEASURE 1/8 442 | 2, 443 | 2, 444 | #MEASURE 3/8 445 | 2, 446 | #MEASURE 1/4 447 | 2, 448 | #GOGOSTART 449 | 4, 450 | 4, 451 | #GOGOEND 452 | #MEASURE 1/8 453 | 2, 454 | 2, 455 | 2, 456 | #MEASURE 1/4 457 | 2, 458 | #MEASURE 1/8 459 | 2, 460 | 2, 461 | #MEASURE 1/4 462 | 2, 463 | #MEASURE 1/8 464 | 2, 465 | #MEASURE 1/4 466 | 2, 467 | #GOGOSTART 468 | 4, 469 | 4, 470 | #GOGOEND 471 | 2, 472 | #MEASURE 1/8 473 | 2, 474 | 2, 475 | #MEASURE 1/4 476 | 2, 477 | #MEASURE 1/8 478 | 2, 479 | #MEASURE 1/4 480 | 2, 481 | 2, 482 | #MEASURE 1/8 483 | 2, 484 | #MEASURE 2/4 485 | 2, 486 | #MEASURE 1/8 487 | 2, 488 | #MEASURE 1/4 489 | 2, 490 | #MEASURE 1/8 491 | 2, 492 | #MEASURE 1/4 493 | 2, 494 | #GOGOSTART 495 | #MEASURE 5/4 496 | 4 497 | #GOGOEND 498 | 0000, 499 | #GOGOSTART 500 | #MEASURE 4/4 501 | #SCROLL 1 502 | 1020201020221020, 503 | 1022100040004000, 504 | 1022201020201020, 505 | 1122100040004000, 506 | 1022221020112010, 507 | 0011221022102000, 508 | 33034043, 509 | 03402020, 510 | 33, 511 | 3033, 512 | , 513 | , 514 | 3, 515 | #BARLINEOFF 516 | , 517 | #GOGOEND 518 | , 519 | , 520 | #SCROLL 0.5 521 | 0002000000000000, 522 | 523 | #BRANCHEND 524 | 525 | 526 | #END 527 | 528 | 529 | COURSE:Hard 530 | LEVEL:6 531 | BALLOON:30,3 532 | SCOREINIT:550 533 | SCOREDIFF:142 534 | 535 | 536 | #START 537 | 538 | 539 | #SCROLL 0.98 540 | 3, 541 | #BPMCHANGE 201.06 542 | #SCROLL 0.96 543 | 3, 544 | #BPMCHANGE 188.46 545 | #SCROLL 1.03 546 | 3, 547 | #BPMCHANGE 194.61 548 | #SCROLL 1 549 | 7, 550 | , 551 | , 552 | , 553 | 8, 554 | , 555 | #BPMCHANGE 195 556 | 12121201, 557 | 01121020, 558 | 12121201, 559 | 01121200, 560 | 12121202, 561 | 02121020, 562 | 10102205, 563 | 000000000000000000000000000000000008000000000000, 564 | 1121 565 | 566 | #GOGOSTART 567 | 4021, 568 | 569 | #GOGOEND 570 | 0121 571 | 572 | #GOGOSTART 573 | 4040, 574 | 575 | #GOGOEND 576 | 11212121, 577 | 578 | #GOGOSTART 579 | 4444, 580 | 581 | #GOGOEND 582 | 1121 583 | 584 | #GOGOSTART 585 | 4021, 586 | 587 | #GOGOEND 588 | 0121 589 | 590 | #GOGOSTART 591 | 4040, 592 | 593 | #GOGOEND 594 | 11212121, 595 | 000000100000200000000000500000000000000008000000, 596 | 100000000000200000100000000000500000000008000000, 597 | 100000000000200000100000000000500000000008000000, 598 | 100000000000200000100000000000500000000008000000, 599 | 10212000, 600 | #BARLINEOFF 601 | 22, 602 | 20002022, 603 | #BARLINEON 604 | 22224444, 605 | 32121201, 606 | 01121020, 607 | 12121201, 608 | 01121200, 609 | 12121202, 610 | 02121020, 611 | 10102105, 612 | 000000000000000000000000000000000008000000000000, 613 | 10012102, 614 | 01122001, 615 | 10102201, 616 | 01011011, 617 | 10011102, 618 | 01122020, 619 | 5, 620 | , 621 | , 622 | 000000000000000000000000000000000000000000000008, 623 | , 624 | , 625 | 626 | #GOGOSTART 627 | #BRANCHSTART p,0,0 628 | #N 629 | 11210112, 630 | 01104040, 631 | 11210112, 632 | 02104040, 633 | 10112021, 634 | 02021020, 635 | 33033044, 636 | 000000600000000000000000000000000000000008000000, 637 | 11210112, 638 | 01104040, 639 | 11210212, 640 | 12104040, 641 | 10222021, 642 | 02221020, 643 | 34034044, 644 | 03307008, 645 | 33, 646 | 3033, 647 | #GOGOEND 648 | , 649 | 650 | #E 651 | 11210112, 652 | 01104040, 653 | 11210112, 654 | 02104040, 655 | 10112021, 656 | 02021020, 657 | 33033044, 658 | 000000600000000000000000000000000000000008000000, 659 | 11210112, 660 | 01104040, 661 | 11210212, 662 | 12104040, 663 | 10222021, 664 | 02221020, 665 | 34034044, 666 | 03307008, 667 | 33, 668 | 3033, 669 | #GOGOEND 670 | , 671 | 672 | #M 673 | 11210112, 674 | 01104040, 675 | 11210112, 676 | 02104040, 677 | 10112021, 678 | 02021020, 679 | 33033044, 680 | 000000600000000000000000000000000000000008000000, 681 | 11210112, 682 | 01104040, 683 | 11210212, 684 | 12104040, 685 | 10222021, 686 | 02221020, 687 | 34034044, 688 | 03307008, 689 | 33, 690 | 3033, 691 | #GOGOEND 692 | , 693 | 694 | #BRANCHSTART p,999,999 695 | #N 696 | , 697 | 600000000000000008000000100000200000100000000000, 698 | 600000000000000008000000100000200000100000000000, 699 | 12121211, 700 | 12121212, 701 | 600000000000000008000000100000200000100000100000, 702 | 600000000000000008000000100000200000100000100000, 703 | 12121211, 704 | 12121222, 705 | 706 | #SECTION 707 | 3111, 708 | 3111, 709 | 6, 710 | 000000000000000000000000000000000000000000000008, 711 | , 712 | , 713 | 714 | #E 715 | , 716 | 600000000000000008000000100000200000100000000000, 717 | 600000000000000008000000100000200000100000000000, 718 | 12121211, 719 | 12121212, 720 | 600000000000000008000000100000200000100000100000, 721 | 600000000000000008000000100000200000100000100000, 722 | 12121211, 723 | 12121222, 724 | 725 | #SECTION 726 | 3111, 727 | 3111, 728 | 6, 729 | 000000000000000000000000000000000000000000000008, 730 | , 731 | , 732 | 733 | #M 734 | , 735 | 600000000000000008000000100000200000100000000000, 736 | 600000000000000008000000100000200000100000000000, 737 | 12121211, 738 | 12121212, 739 | 600000000000000008000000100000200000100000100000, 740 | 600000000000000008000000100000200000100000100000, 741 | 12121211, 742 | 12121222, 743 | 744 | #SECTION 745 | 3111, 746 | 3111, 747 | 6, 748 | 000000000000000000000000000000000000000000000008, 749 | , 750 | , 751 | 752 | #BRANCHSTART r,0,1 753 | #N 754 | , 755 | #BARLINEOFF 756 | , 757 | , 758 | 0002, 759 | #BARLINEON 760 | #MEASURE 1/4 761 | #SCROLL 0.75 762 | , 763 | #MEASURE 1/8 764 | , 765 | #MEASURE 1/4 766 | , 767 | , 768 | #MEASURE 3/8 769 | , 770 | #MEASURE 1/4 771 | , 772 | #GOGOSTART 773 | , 774 | , 775 | #GOGOEND 776 | , 777 | #MEASURE 1/8 778 | , 779 | #MEASURE 1/4 780 | , 781 | , 782 | , 783 | #MEASURE 1/8 784 | , 785 | #MEASURE 1/4 786 | , 787 | #GOGOSTART 788 | , 789 | , 790 | #GOGOEND 791 | , 792 | , 793 | #MEASURE 3/8 794 | , 795 | #MEASURE 1/4 796 | , 797 | , 798 | #MEASURE 1/8 799 | , 800 | #MEASURE 2/4 801 | , 802 | #MEASURE 1/8 803 | , 804 | #MEASURE 1/4 805 | , 806 | #MEASURE 1/8 807 | , 808 | #MEASURE 1/4 809 | , 810 | #GOGOSTART 811 | #MEASURE 5/4 812 | 0 813 | #GOGOEND 814 | 0000, 815 | #GOGOSTART 816 | #MEASURE 4/4 817 | #SCROLL 1 818 | 11210212, 819 | 02104040, 820 | 11210212, 821 | 12104040, 822 | 10221021, 823 | 02021020, 824 | 33034044, 825 | 03302020, 826 | 33, 827 | 3033, 828 | #GOGOEND 829 | , 830 | , 831 | #GOGOSTART 832 | 3, 833 | #BARLINEOFF 834 | , 835 | #GOGOEND 836 | , 837 | , 838 | #SCROLL 0.5 839 | 0002000000000000, 840 | 841 | #E 842 | , 843 | #BARLINEOFF 844 | , 845 | , 846 | 0002, 847 | #BARLINEON 848 | #MEASURE 1/4 849 | #SCROLL 0.75 850 | , 851 | #MEASURE 1/8 852 | , 853 | #MEASURE 1/4 854 | , 855 | , 856 | #MEASURE 3/8 857 | , 858 | #MEASURE 1/4 859 | , 860 | #GOGOSTART 861 | , 862 | , 863 | #GOGOEND 864 | , 865 | #MEASURE 1/8 866 | , 867 | #MEASURE 1/4 868 | , 869 | , 870 | , 871 | #MEASURE 1/8 872 | , 873 | #MEASURE 1/4 874 | , 875 | #GOGOSTART 876 | , 877 | , 878 | #GOGOEND 879 | , 880 | , 881 | #MEASURE 3/8 882 | , 883 | #MEASURE 1/4 884 | , 885 | , 886 | #MEASURE 1/8 887 | , 888 | #MEASURE 2/4 889 | , 890 | #MEASURE 1/8 891 | , 892 | #MEASURE 1/4 893 | , 894 | #MEASURE 1/8 895 | , 896 | #MEASURE 1/4 897 | , 898 | #GOGOSTART 899 | #MEASURE 5/4 900 | 0 901 | #GOGOEND 902 | 0000, 903 | #GOGOSTART 904 | #MEASURE 4/4 905 | #SCROLL 1 906 | 11210212, 907 | 02104040, 908 | 11210212, 909 | 12104040, 910 | 10221021, 911 | 02021020, 912 | 33034044, 913 | 03302020, 914 | 33, 915 | 3033, 916 | #GOGOEND 917 | , 918 | , 919 | #GOGOSTART 920 | 3, 921 | #BARLINEOFF 922 | , 923 | #GOGOEND 924 | , 925 | , 926 | #SCROLL 0.5 927 | 0002000000000000, 928 | 929 | #M 930 | , 931 | #BARLINEOFF 932 | , 933 | , 934 | 0002, 935 | #BARLINEON 936 | #MEASURE 1/4 937 | #SCROLL 0.75 938 | 2, 939 | #MEASURE 1/8 940 | 2, 941 | #MEASURE 1/4 942 | 2, 943 | 2, 944 | #MEASURE 3/8 945 | 2, 946 | #MEASURE 1/4 947 | 2, 948 | #GOGOSTART 949 | 4, 950 | 4, 951 | #GOGOEND 952 | 2, 953 | #MEASURE 1/8 954 | 2, 955 | #MEASURE 1/4 956 | 2, 957 | 2, 958 | 2, 959 | #MEASURE 1/8 960 | 2, 961 | #MEASURE 1/4 962 | 2, 963 | #GOGOSTART 964 | 4, 965 | 4, 966 | #GOGOEND 967 | 2, 968 | 2, 969 | #MEASURE 3/8 970 | 2, 971 | #MEASURE 1/4 972 | 2, 973 | 2, 974 | #MEASURE 1/8 975 | 2, 976 | #MEASURE 2/4 977 | 2, 978 | #MEASURE 1/8 979 | 2, 980 | #MEASURE 1/4 981 | 2, 982 | #MEASURE 1/8 983 | 2, 984 | #MEASURE 1/4 985 | 2, 986 | #GOGOSTART 987 | #MEASURE 5/4 988 | 4 989 | #GOGOEND 990 | 0000, 991 | #GOGOSTART 992 | #MEASURE 4/4 993 | #SCROLL 1 994 | 11210212, 995 | 0011100040004000, 996 | 11210212, 997 | 1011100040004000, 998 | 10221021, 999 | 0022202010102000, 1000 | 33034044, 1001 | 03302020, 1002 | 33, 1003 | 3033, 1004 | #GOGOEND 1005 | , 1006 | , 1007 | #GOGOSTART 1008 | 3, 1009 | #BARLINEOFF 1010 | , 1011 | #GOGOEND 1012 | , 1013 | , 1014 | #SCROLL 0.5 1015 | 0002000000000000, 1016 | 1017 | #BRANCHEND 1018 | 1019 | 1020 | #END 1021 | 1022 | 1023 | //COURSE:Normal 1024 | //LEVEL:5 1025 | //BALLOON:30,2 1026 | //SCOREINIT:530 1027 | //SCOREDIFF:145 1028 | // 1029 | // 1030 | //#START 1031 | // 1032 | // 1033 | //#SCROLL 0.98 1034 | //3, 1035 | //#BPMCHANGE 201.06 1036 | //#SCROLL 0.96 1037 | //3, 1038 | //#BPMCHANGE 188.46 1039 | //#SCROLL 1.03 1040 | //3, 1041 | //#BPMCHANGE 194.61 1042 | //#SCROLL 1 1043 | //7, 1044 | //, 1045 | //, 1046 | //, 1047 | //8, 1048 | //, 1049 | //#BPMCHANGE 195 1050 | //1110, 1051 | //1110, 1052 | //1110, 1053 | //11101000, 1054 | //1110, 1055 | //1110, 1056 | //10101105, 1057 | //000000000000000000000000000000000008000000000000, 1058 | //11 1059 | // 1060 | //#GOGOSTART 1061 | //40, 1062 | // 1063 | //#GOGOEND 1064 | //11 1065 | // 1066 | //#GOGOSTART 1067 | //44, 1068 | // 1069 | //#GOGOEND 1070 | //1120, 1071 | // 1072 | //#GOGOSTART 1073 | //4444, 1074 | // 1075 | //#GOGOEND 1076 | //11 1077 | // 1078 | //#GOGOSTART 1079 | //40, 1080 | // 1081 | //#GOGOEND 1082 | //11 1083 | // 1084 | //#GOGOSTART 1085 | //44, 1086 | // 1087 | //#GOGOEND 1088 | //1120, 1089 | //100000000000200000000000500000000008000000000000, 1090 | //10100100, 1091 | //10100100, 1092 | //10100100, 1093 | //1120, 1094 | //#BARLINEOFF 1095 | //22, 1096 | //2022, 1097 | //#BARLINEON 1098 | //2244, 1099 | //3110, 1100 | //1110, 1101 | //1110, 1102 | //11101000, 1103 | //1110, 1104 | //1110, 1105 | //10102205, 1106 | //000000000000000000000000000000000008000000000000, 1107 | //10011000, 1108 | //1120, 1109 | //1120, 1110 | //1110, 1111 | //10011000, 1112 | //1120, 1113 | //5, 1114 | //, 1115 | //, 1116 | //000000000000000000000000000000000000000000000008, 1117 | //, 1118 | //, 1119 | // 1120 | //#GOGOSTART 1121 | //#BRANCHSTART p,0,0 1122 | //#N 1123 | //10101110, 1124 | //1144, 1125 | //10101110, 1126 | //1144, 1127 | //10111001, 1128 | //01011000, 1129 | //33033033, 1130 | //000000600000000000000000000000000008000000000000, 1131 | //10101110, 1132 | //1144, 1133 | //10102220, 1134 | //1144, 1135 | //10111002, 1136 | //02202000, 1137 | //33033044, 1138 | //03307080, 1139 | //33, 1140 | //3033, 1141 | // 1142 | //#GOGOEND 1143 | //, 1144 | // 1145 | //#E 1146 | //10101110, 1147 | //1144, 1148 | //10101110, 1149 | //1144, 1150 | //10111001, 1151 | //01011000, 1152 | //33033033, 1153 | //000000600000000000000000000000000008000000000000, 1154 | //10101110, 1155 | //1144, 1156 | //10102220, 1157 | //1144, 1158 | //10111002, 1159 | //02202000, 1160 | //33033044, 1161 | //03307080, 1162 | //33, 1163 | //3033, 1164 | // 1165 | //#GOGOEND 1166 | //, 1167 | // 1168 | //#M 1169 | //10101110, 1170 | //1144, 1171 | //10101110, 1172 | //1144, 1173 | //10111001, 1174 | //01011000, 1175 | //33033033, 1176 | //000000600000000000000000000000000008000000000000, 1177 | //10101110, 1178 | //1144, 1179 | //10102220, 1180 | //1144, 1181 | //10111002, 1182 | //02202000, 1183 | //33033044, 1184 | //03307080, 1185 | //33, 1186 | //3033, 1187 | // 1188 | //#GOGOEND 1189 | //, 1190 | // 1191 | //#BRANCHSTART p,999,999 1192 | //#N 1193 | //, 1194 | //500000000000000008000000100000000000100000000000, 1195 | //500000000000000008000000100000000000100000000000, 1196 | //10101110, 1197 | //11102220, 1198 | //500000000000000008000000200000000000200000000000, 1199 | //500000000000000008000000200000000000200000000000, 1200 | //10101110, 1201 | //11102220, 1202 | // 1203 | //3111, 1204 | //3111, 1205 | //5, 1206 | //000000000000000000000000000000000000000000000008, 1207 | //, 1208 | //, 1209 | // 1210 | //#E 1211 | //, 1212 | //500000000000000008000000100000000000100000000000, 1213 | //500000000000000008000000100000000000100000000000, 1214 | //10101110, 1215 | //11102220, 1216 | //500000000000000008000000200000000000200000000000, 1217 | //500000000000000008000000200000000000200000000000, 1218 | //10101110, 1219 | //11102220, 1220 | // 1221 | //3111, 1222 | //3111, 1223 | //5, 1224 | //000000000000000000000000000000000000000000000008, 1225 | //, 1226 | //, 1227 | // 1228 | //#M 1229 | //, 1230 | //500000000000000008000000100000000000100000000000, 1231 | //500000000000000008000000100000000000100000000000, 1232 | //10101110, 1233 | //11102220, 1234 | //500000000000000008000000200000000000200000000000, 1235 | //500000000000000008000000200000000000200000000000, 1236 | //10101110, 1237 | //11102220, 1238 | // 1239 | //3111, 1240 | //3111, 1241 | //5, 1242 | //000000000000000000000000000000000000000000000008, 1243 | //, 1244 | //, 1245 | // 1246 | //#BRANCHSTART p,0,0 1247 | //#N 1248 | //, 1249 | //#BARLINEOFF 1250 | //#SCROLL 0.75 1251 | //, 1252 | //, 1253 | //0002, 1254 | //#BARLINEON 1255 | //, 1256 | //00 1257 | //#GOGOSTART 1258 | //#MEASURE 2/4 1259 | //2, 1260 | //2, 1261 | //#GOGOEND 1262 | //#MEASURE 4/4 1263 | //, 1264 | //00 1265 | //#GOGOSTART 1266 | //22, 1267 | //#GOGOEND 1268 | //02, 1269 | //02, 1270 | //200200 1271 | //#GOGOSTART 1272 | //40, 1273 | //#BARLINEOFF 1274 | //, 1275 | //#GOGOSTART 1276 | //#BARLINEON 1277 | //#SCROLL 1 1278 | //10101110, 1279 | //1144, 1280 | //10102220, 1281 | //1144, 1282 | //10111002, 1283 | //02022000, 1284 | //33033044, 1285 | //03302020, 1286 | //33, 1287 | //3033, 1288 | //#GOGOEND 1289 | //, 1290 | //, 1291 | //#GOGOSTART 1292 | //3, 1293 | //, 1294 | //#GOGOEND 1295 | //, 1296 | //#SCROLL 0.5 1297 | //, 1298 | //0002000000000000, 1299 | // 1300 | // 1301 | //#E 1302 | //, 1303 | //#BARLINEOFF 1304 | //#SCROLL 0.75 1305 | //, 1306 | //, 1307 | //0002, 1308 | //#BARLINEON 1309 | //, 1310 | //00 1311 | //#GOGOSTART 1312 | //#MEASURE 2/4 1313 | //2, 1314 | //2, 1315 | //#GOGOEND 1316 | //#MEASURE 4/4 1317 | //, 1318 | //00 1319 | //#GOGOSTART 1320 | //22, 1321 | //#GOGOEND 1322 | //02, 1323 | //02, 1324 | //200200 1325 | //#GOGOSTART 1326 | //40, 1327 | //#BARLINEOFF 1328 | //, 1329 | //#GOGOSTART 1330 | //#BARLINEON 1331 | //#SCROLL 1 1332 | //10101110, 1333 | //1144, 1334 | //10102220, 1335 | //1144, 1336 | //10111002, 1337 | //02022000, 1338 | //33033044, 1339 | //03302020, 1340 | //33, 1341 | //3033, 1342 | //#GOGOEND 1343 | //, 1344 | //, 1345 | //#GOGOSTART 1346 | //3, 1347 | //, 1348 | //#GOGOEND 1349 | //, 1350 | //#SCROLL 0.5 1351 | //, 1352 | //0002000000000000, 1353 | // 1354 | //#M 1355 | //, 1356 | //#BARLINEOFF 1357 | //#SCROLL 0.75 1358 | //, 1359 | //, 1360 | //0002, 1361 | //#BARLINEON 1362 | //, 1363 | //00 1364 | //#GOGOSTART 1365 | //#MEASURE 2/4 1366 | //2, 1367 | //2, 1368 | //#GOGOEND 1369 | //#MEASURE 4/4 1370 | //, 1371 | //00 1372 | //#GOGOSTART 1373 | //22, 1374 | //#GOGOEND 1375 | //02, 1376 | //02, 1377 | //200200 1378 | //#GOGOSTART 1379 | //40, 1380 | //#BARLINEOFF 1381 | //, 1382 | //#GOGOSTART 1383 | //#BARLINEON 1384 | //#SCROLL 1 1385 | //10101110, 1386 | //1144, 1387 | //10102220, 1388 | //1144, 1389 | //10111002, 1390 | //02022000, 1391 | //33033044, 1392 | //03302020, 1393 | //33, 1394 | //3033, 1395 | //#GOGOEND 1396 | //, 1397 | //, 1398 | //#GOGOSTART 1399 | //3, 1400 | //, 1401 | //#GOGOEND 1402 | //, 1403 | //#SCROLL 0.5 1404 | //, 1405 | //0002000000000000, 1406 | // 1407 | //#BRANCHEND 1408 | // 1409 | // 1410 | //#END 1411 | // 1412 | // 1413 | //COURSE:Easy 1414 | //LEVEL:3 1415 | //BALLOON:17 1416 | //SCOREINIT:480 1417 | //SCOREDIFF:160 1418 | // 1419 | // 1420 | //#START 1421 | // 1422 | // 1423 | //#SCROLL 0.98 1424 | //3, 1425 | //#BPMCHANGE 201.06 1426 | //#SCROLL 0.96 1427 | //3, 1428 | //#BPMCHANGE 188.46 1429 | //#SCROLL 1.03 1430 | //3, 1431 | //#BPMCHANGE 194.61 1432 | //#SCROLL 1 1433 | //7, 1434 | //, 1435 | //, 1436 | //, 1437 | //8, 1438 | //, 1439 | //#BPMCHANGE 195 1440 | //11, 1441 | //1110, 1442 | //11, 1443 | //1110, 1444 | //11, 1445 | //1110, 1446 | //10002005, 1447 | //000000000000000000000000000008000000000000000000, 1448 | //1 1449 | // 1450 | //#GOGOSTART 1451 | //3, 1452 | // 1453 | //#GOGOEND 1454 | //10 1455 | // 1456 | //#GOGOSTART 1457 | //33, 1458 | // 1459 | //#GOGOEND 1460 | //11, 1461 | // 1462 | //#GOGOSTART 1463 | //3333, 1464 | // 1465 | //#GOGOEND 1466 | //1 1467 | // 1468 | //#GOGOSTART 1469 | //3, 1470 | // 1471 | //#GOGOEND 1472 | //10 1473 | // 1474 | //#GOGOSTART 1475 | //33, 1476 | // 1477 | //#GOGOEND 1478 | //11, 1479 | //500000000000000000000000000008000000000000000000, 1480 | //1, 1481 | //11, 1482 | //1, 1483 | //12, 1484 | //#BARLINEOFF 1485 | //22, 1486 | //22, 1487 | //#BARLINEON 1488 | //2022, 1489 | //41, 1490 | //1110, 1491 | //11, 1492 | //1110, 1493 | //11, 1494 | //1110, 1495 | //10002005, 1496 | //000000000000000000000000000008000000000000000000, 1497 | //1, 1498 | //12, 1499 | //11, 1500 | //1, 1501 | //1, 1502 | //12, 1503 | //5, 1504 | //, 1505 | //, 1506 | //000000000000000000000000000000000000000000000008, 1507 | //, 1508 | //, 1509 | // 1510 | //#GOGOSTART 1511 | //#BRANCHSTART p,0,0 1512 | //#N 1513 | //, 1514 | //, 1515 | //, 1516 | //, 1517 | //, 1518 | //, 1519 | //, 1520 | //, 1521 | //, 1522 | //, 1523 | //, 1524 | //, 1525 | //, 1526 | //, 1527 | //, 1528 | //, 1529 | //, 1530 | //, 1531 | //, 1532 | //, 1533 | // 1534 | //#E 1535 | //, 1536 | //, 1537 | //, 1538 | //, 1539 | //, 1540 | //, 1541 | //, 1542 | //, 1543 | //, 1544 | //, 1545 | //, 1546 | //, 1547 | //, 1548 | //, 1549 | //, 1550 | //, 1551 | //, 1552 | //, 1553 | //, 1554 | // 1555 | //#M 1556 | //11, 1557 | //1033, 1558 | //22, 1559 | //2033, 1560 | //11, 1561 | //1110, 1562 | //30030030, 1563 | //000000600000000000000000000008000000000000000000, 1564 | //11, 1565 | //1044, 1566 | //22, 1567 | //2033, 1568 | //11, 1569 | //2220, 1570 | //30030030, 1571 | //03000000, 1572 | //600000000000000000000000000008000000000000000000, 1573 | //33, 1574 | // 1575 | //#GOGOEND 1576 | //, 1577 | // 1578 | //#BRANCHSTART p,999,999 1579 | //#N 1580 | //, 1581 | //500000000000000000000000000008000000000000000000, 1582 | //500000000000000000000000000008000000000000000000, 1583 | //11, 1584 | //1110, 1585 | //500000000000000000000000000008000000000000000000, 1586 | //500000000000000000000000000008000000000000000000, 1587 | //11, 1588 | //2220, 1589 | //11, 1590 | //11, 1591 | //5, 1592 | //000000000000000000000000000000000000000000000008, 1593 | //, 1594 | // 1595 | //#E 1596 | //, 1597 | //, 1598 | //, 1599 | //, 1600 | //, 1601 | //, 1602 | //, 1603 | //, 1604 | //, 1605 | //, 1606 | //, 1607 | //, 1608 | //, 1609 | //, 1610 | //, 1611 | // 1612 | //#M 1613 | //, 1614 | //, 1615 | //, 1616 | //, 1617 | //, 1618 | //, 1619 | //, 1620 | //, 1621 | //, 1622 | //, 1623 | //, 1624 | //, 1625 | //, 1626 | //, 1627 | //, 1628 | // 1629 | //#BRANCHSTART p,0,0 1630 | //#N 1631 | //, 1632 | //, 1633 | //, 1634 | //, 1635 | //, 1636 | //00 1637 | //#GOGOSTART 1638 | //00, 1639 | //#GOGOEND 1640 | //, 1641 | //00 1642 | //#GOGOSTART 1643 | //00, 1644 | //#GOGOEND 1645 | //, 1646 | //, 1647 | //000000 1648 | //#GOGOSTART 1649 | //00, 1650 | //, 1651 | //, 1652 | //, 1653 | //, 1654 | //, 1655 | //, 1656 | //, 1657 | //, 1658 | //, 1659 | //, 1660 | //, 1661 | //, 1662 | //, 1663 | //, 1664 | //, 1665 | //, 1666 | //, 1667 | //, 1668 | // 1669 | //#E 1670 | //, 1671 | //, 1672 | //, 1673 | //, 1674 | //, 1675 | //00 1676 | //#GOGOSTART 1677 | //00, 1678 | //#GOGOEND 1679 | //, 1680 | //00 1681 | //#GOGOSTART 1682 | //00, 1683 | //#GOGOEND 1684 | //, 1685 | //, 1686 | //000000 1687 | //#GOGOSTART 1688 | //00, 1689 | //, 1690 | //, 1691 | //, 1692 | //, 1693 | //, 1694 | //, 1695 | //, 1696 | //, 1697 | //, 1698 | //, 1699 | //, 1700 | //, 1701 | //, 1702 | //, 1703 | //, 1704 | //, 1705 | //, 1706 | //, 1707 | // 1708 | //#M 1709 | //, 1710 | //#BARLINEOFF 1711 | //, 1712 | //, 1713 | //, 1714 | //#BARLINEON 1715 | //#SCROLL 0.75 1716 | //, 1717 | //00 1718 | //#GOGOSTART 1719 | //22, 1720 | //#GOGOEND 1721 | //, 1722 | //00 1723 | //#GOGOSTART 1724 | //22, 1725 | //#GOGOEND 1726 | //, 1727 | //2, 1728 | //200 1729 | //#GOGOSTART 1730 | //4, 1731 | //#GOGOEND 1732 | //#BARLINEOFF 1733 | //, 1734 | //#GOGOSTART 1735 | //#BARLINEON 1736 | //#SCROLL 1 1737 | //11, 1738 | //1044, 1739 | //11, 1740 | //2033, 1741 | //11, 1742 | //2220, 1743 | //30030030, 1744 | //03000000, 1745 | //33, 1746 | //3033, 1747 | //#GOGOEND 1748 | //, 1749 | //, 1750 | //#GOGOSTART 1751 | //3, 1752 | //, 1753 | //#GOGOEND 1754 | //, 1755 | //#SCROLL 0.5 1756 | //, 1757 | //0002000000000000, 1758 | // 1759 | //#BRANCHEND 1760 | // 1761 | // 1762 | //#END 1763 | // 1764 | --------------------------------------------------------------------------------