├── .gitignore ├── DENSYA_CON_T01.py ├── JRESim_Dengo.py ├── JRESim_Type2.py ├── LICENSE ├── README.md ├── SwitchDenGo.py ├── requirements_Dengo.txt └── requirements_Type2.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | -------------------------------------------------------------------------------- /DENSYA_CON_T01.py: -------------------------------------------------------------------------------- 1 | #coding: utf-8 2 | import libusb_package 3 | import usb.core 4 | import usb.backend.libusb1 5 | import time 6 | 7 | libusb1_backend = usb.backend.libusb1.get_backend(find_library=libusb_package.find_library) 8 | 9 | class DENSYA_CON_T01(): 10 | BR_LEVEL = {0x79: 0, 0x8A: 1, 0x94: 2, 0x9A: 3, 0xA2: 4, 0xA8: 5, 0xAF: 6, 0xB2: 7, 0xB5: 8, 0xB9: 9} 11 | MC_LEVEL = {0x81: 0, 0x6D: 1, 0x54: 2, 0x3F: 3, 0x21: 4, 0x00: 5} 12 | 13 | def __init__(self): 14 | devices = usb.core.find(find_all=True, backend=libusb1_backend, idVendor=0x0ae4, idProduct=0x0004) 15 | for device in devices: 16 | self.device = device 17 | 18 | # 正しくアサインされたかの検査 19 | self.device 20 | 21 | self.device.reset() 22 | time.sleep(0.1) 23 | self.device.reset() 24 | 25 | def loadStatus(self): 26 | self.brake_knotch = None 27 | self.accel_knotch = None 28 | self.buttons = [] 29 | 30 | # 3回試行する 31 | for i in range(3): 32 | try: 33 | # 129: 固定されたエンドポイント 34 | [_01, BR, MC, PD, HT, BT] = self.device.read(129, 8, 10) 35 | if BR != 0xFF: 36 | self.brake_knotch = self.BR_LEVEL[BR] 37 | if MC != 0xFF: 38 | self.accel_knotch = self.MC_LEVEL[MC] 39 | 40 | if PD == 0xFF: 41 | self.buttons.append("HONE") 42 | 43 | if HT == 0x06: 44 | self.buttons.append("TYPE2_LEFT") 45 | elif HT == 0x02: 46 | self.buttons.append("TYPE2_RIGHT") 47 | elif HT == 0x00: 48 | self.buttons.append("TYPE2_UP") 49 | elif HT == 0x04: 50 | self.buttons.append("TYPE2_DOWN") 51 | 52 | if BT == 0x02: 53 | self.buttons.append("TYPE2_A") 54 | elif BT == 0x01: 55 | self.buttons.append("TYPE2_B") 56 | elif BT == 0x04: 57 | self.buttons.append("TYPE2_C") 58 | elif BT == 0x08: 59 | self.buttons.append("TYPE2_D") 60 | 61 | except KeyError: 62 | pass 63 | 64 | except usb.core.USBTimeoutError: 65 | pass 66 | 67 | except usb.core.USBError: 68 | exit() 69 | 70 | finally: 71 | self.buttons = list(set(self.buttons)) 72 | 73 | if __name__ == '__main__': 74 | controller = DENSYA_CON_T01() 75 | controller.read() 76 | print(controller.mascon_level, controller.brake_level) 77 | -------------------------------------------------------------------------------- /JRESim_Dengo.py: -------------------------------------------------------------------------------- 1 | #coding: utf-8 2 | 3 | import SwitchDenGo 4 | import keyboard 5 | import time 6 | 7 | print("このソフトウェアは、JR東日本トレインシミュレータ(JR EAST Train Simulator)を") 8 | print("ゲーム向けマスコンで操作できるようにするための、同人ソフトウェアです。") 9 | print("JR東日本およびその関連会社、また音楽館とは一切関係がありません。") 10 | print("製作者Twitter: @mipsparc , GitHub: https://github.com/mipsparc") 11 | print("現在はZUIKIの1ハンSwitchマスコンとタイトーのPS2 Type2 2ハンドルマスコンに対応しています") 12 | print() 13 | print("JRESim_Dengo Version1.1") 14 | print("使い方: シミュレータ起動前にこのプログラムを起動するだけです。") 15 | print("運転画面になったら、一旦非常ブレーキ(EB)に入れてください。") 16 | print("Xボタン:前位置、Bボタン:後位置、Aボタン:EBリセット") 17 | print("終了時はこのウィンドウをそのまま閉じてください。") 18 | 19 | dengo = SwitchDenGo.SwitchDenGo() 20 | P = 0 21 | B = 0 22 | while True: 23 | dengo.loadStatus() 24 | 25 | plus_knotch = 0 26 | if P > dengo.accel_knotch: 27 | plus_knotch = P - dengo.accel_knotch 28 | if B < dengo.brake_knotch: 29 | plus_knotch = dengo.brake_knotch - B 30 | for i in range(plus_knotch): 31 | keyboard.press_and_release("q") 32 | 33 | minus_knotch = 0 34 | if P < dengo.accel_knotch: 35 | minus_knotch = dengo.accel_knotch - P 36 | if B > dengo.brake_knotch: 37 | minus_knotch = B - dengo.brake_knotch 38 | if dengo.brake_knotch == 9: 39 | keyboard.press_and_release("1") 40 | time.sleep(0.5) 41 | else: 42 | for i in range(minus_knotch): 43 | keyboard.press_and_release("z") 44 | 45 | P = dengo.accel_knotch 46 | B = dengo.brake_knotch 47 | 48 | if "SW_X" in dengo.buttons: 49 | keyboard.send("up") 50 | if "SW_B" in dengo.buttons: 51 | keyboard.send("down") 52 | if "SW_A" in dengo.buttons: 53 | keyboard.press_and_release("e") 54 | if "SW_HOME" in dengo.buttons: 55 | keyboard.send("enter") 56 | if "SW_CIRCLE" in dengo.buttons: 57 | keyboard.send("backspace") 58 | 59 | time.sleep(0.05) 60 | -------------------------------------------------------------------------------- /JRESim_Type2.py: -------------------------------------------------------------------------------- 1 | #coding: utf-8 2 | 3 | import DENSYA_CON_T01 4 | import keyboard 5 | import time 6 | 7 | print("このソフトウェアは、JR東日本トレインシミュレータ(JR EAST Train Simulator)を") 8 | print("ゲーム向けマスコンで操作できるようにするための、同人ソフトウェアです。") 9 | print("JR東日本およびその関連会社、また音楽館とは一切関係がありません。") 10 | print("製作者Twitter: @mipsparc , GitHub: https://github.com/mipsparc") 11 | print("現在はZUIKIの1ハンSwitchマスコンとタイトーのPS2 Type2 2ハンドルマスコンに対応しています") 12 | print() 13 | print("JRESim_Type2 Version1.1") 14 | print("使い方: シミュレータ起動前にこのプログラムを起動するだけです。") 15 | print("運転画面になったら、一旦マスコンは切、ブレーキは非常ブレーキに入れてください。") 16 | print("上ボタン:前位置、下ボタン:後位置、Aボタン:EBリセット、Bボタンまたはペダル:ホーン") 17 | print("終了時はこのウィンドウをそのまま閉じてください。") 18 | 19 | dengo = DENSYA_CON_T01.DENSYA_CON_T01() 20 | P = 0 21 | B = 0 22 | while True: 23 | dengo.loadStatus() 24 | 25 | if dengo.accel_knotch is not None: 26 | plus_p = 0 27 | minus_p = 0 28 | if P > dengo.accel_knotch: 29 | minus_p = P - dengo.accel_knotch 30 | if P < dengo.accel_knotch: 31 | plus_p = dengo.accel_knotch - P 32 | for i in range(plus_p): 33 | keyboard.press_and_release("z") 34 | for i in range(minus_p): 35 | keyboard.press_and_release("a") 36 | P = dengo.accel_knotch 37 | 38 | if dengo.brake_knotch is not None: 39 | if dengo.brake_knotch == 9: 40 | keyboard.press_and_release("/") 41 | time.sleep(0.5) 42 | else: 43 | plus_b = 0 44 | minus_b = 0 45 | if B > dengo.brake_knotch: 46 | minus_b = B - dengo.brake_knotch 47 | if B < dengo.brake_knotch: 48 | plus_b = dengo.brake_knotch - B 49 | for i in range(plus_b): 50 | keyboard.press_and_release(".") 51 | for i in range(minus_b): 52 | keyboard.press_and_release(",") 53 | B = dengo.brake_knotch 54 | 55 | if "TYPE2_UP" in dengo.buttons: 56 | keyboard.send("up") 57 | if "TYPE2_DOWN" in dengo.buttons: 58 | keyboard.send("down") 59 | if "TYPE2_A" in dengo.buttons: 60 | keyboard.press_and_release("e") 61 | if "HONE" in dengo.buttons or "TYPE2_B" in dengo.buttons: 62 | keyboard.send("backspace") 63 | 64 | time.sleep(0.02) 65 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 mipsparc 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ご連絡 2 | 製造時期の違いにより、製品によっては正しく動かないようです。 3 | 修正してくださった方がいたので、こちらから取得ください。 4 | https://github.com/advanceboy/JRESim_Dengo/releases/tag/v1.0p1 5 | 6 | # JRESim_Dengo 7 | JR東日本トレインシミュレータ(JR EAST Train Simulator)をゲーム向けマスコンで操作できるようにするための、同人ソフトウェアです。 8 | 9 | ## 現在対応しているマスコン 10 | - ZUIKI Switch向け電車でGOワンハンドルマスコン 11 | - タイトー PS2向け電車でGOツーハンドルマスコン 12 | 13 | ## ライセンス・権利 14 | JR東日本およびその関連会社、また音楽館とは一切関係がありません。 15 | 本ソフトウェアはMITライセンス(オープンソースライセンス)です。 16 | 17 | ## 製作者 18 | Twitter: @mipsparc , GitHub: https://github.com/mipsparc 19 | 20 | ## 使い方 21 | - シミュレータ起動前にこのプログラムを起動するだけです 22 | - 表示された説明を読んで下さい 23 | - 終了時はこのウィンドウを右上のバツボタンで閉じるだけ 24 | -------------------------------------------------------------------------------- /SwitchDenGo.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | import time 3 | 4 | class SwitchDenGo(): 5 | def __init__(self): 6 | pygame.init() 7 | self.joy = pygame.joystick.Joystick(0) 8 | self.joy.init() 9 | 10 | def loadStatus(self): 11 | self.brake_knotch = 0 12 | self.accel_knotch = 0 13 | self.buttons = [] 14 | pygame.event.get() 15 | 16 | # Xボタン 17 | if self.joy.get_button(2): 18 | self.buttons.append("SW_X") 19 | # Yボタン 20 | if self.joy.get_button(3): 21 | self.buttons.append("SW_Y") 22 | # Aボタン 23 | if self.joy.get_button(0): 24 | self.buttons.append("SW_A") 25 | # Bボタン 26 | if self.joy.get_button(1): 27 | self.buttons.append("SW_B") 28 | # ○ボタン 29 | if self.joy.get_button(15): 30 | self.buttons.append("SW_CIRCLE") 31 | # HOMEボタン 32 | if self.joy.get_button(5): 33 | self.buttons.append("SW_HOME") 34 | 35 | knotch_level = self.joy.get_axis(1) 36 | 37 | if knotch_level > 0.95: 38 | self.accel_knotch = 5 39 | elif knotch_level > 0.75: 40 | self.accel_knotch = 4 41 | elif knotch_level > 0.55: 42 | self.accel_knotch = 3 43 | elif knotch_level > 0.3: 44 | self.accel_knotch = 2 45 | elif knotch_level > 0.1: 46 | self.accel_knotch = 1 47 | elif knotch_level > -0.05: 48 | self.accel_knotch = 0 49 | self.brake_knotch = 0 50 | elif knotch_level > -0.25: 51 | self.brake_knotch = 1 52 | elif knotch_level > -0.35: 53 | self.brake_knotch = 2 54 | elif knotch_level > -0.45: 55 | self.brake_knotch = 3 56 | elif knotch_level > -0.55: 57 | self.brake_knotch = 4 58 | elif knotch_level > -0.7: 59 | self.brake_knotch = 5 60 | elif knotch_level > -0.8: 61 | self.brake_knotch = 6 62 | elif knotch_level > -0.9: 63 | self.brake_knotch = 7 64 | elif knotch_level > -1.0: 65 | self.brake_knotch = 8 66 | else: 67 | self.brake_knotch = 9 68 | 69 | if self.brake_knotch > 0: 70 | self.accel_knotch = 0 71 | -------------------------------------------------------------------------------- /requirements_Dengo.txt: -------------------------------------------------------------------------------- 1 | pygame==2.1.2 2 | keyboard==0.13.5 3 | -------------------------------------------------------------------------------- /requirements_Type2.txt: -------------------------------------------------------------------------------- 1 | keyboard==0.13.5 2 | pyusb==1.2.1 3 | libusb-package==1.0.26.0 4 | --------------------------------------------------------------------------------