Linux 也要玩中二节奏!
环境: CachyOS (Arch-based) / KDE Plasma 6 (Wayland) / Wine GE-Proton11-7 (umu-launcher) / Lutris
硬件: 联想小新 2022 (Intel i5-12500H + Iris Xe 核显 & NVIDIA RTX 3060 Laptop)
外设: 基于 LINGNITHM 3.2 的自制手台 (CDC 串口触摸 + HID 键盘 AIR)
游戏: CHUNITHM Mate (SDHD 2.50) + fufubot segatools
0. TL;DR
| 项目 | 结论 |
|---|---|
| Wine 版本 | GE-Proton11-7 (umu 启动) , 必须用 wined3d (DXVK 启动即崩) |
| 渲染 | PROTON_USE_WINED3D=1 + winmm=n,b + d3d*/dxgi 全部 b (builtin) |
| 独显 | __NV_PRIME_RENDER_OFFLOAD=1 + __GLX_VENDOR_LIBRARY_NAME=nvidia |
| 帧数 | wined3d 下默认跑到最高帧数, 用 mangohud fps_limit=120 锁定 120 |
| 触摸 | 面板直连串口 (Wine 内 COM1 → /dev/ttyACM0) , segatools [slider] enable=0 |
| AIR | 面板 AIR 走 HID 键盘 (小键盘 1–6 → vkey 0x61–0x66) , segatools [io3] ir=0 + [ir] ir1..6=0x61..0x66 |
| wine 中文问题 | segatools.ini 里不能写中文注释!Wine 的 INI 解析器会把中文注释的下一行配置整行吞掉 |
| 启动 | Lutris 正常启动 (start.bat) ;预启动脚本做 COM1 映射 |
1. 软硬件栈
1.1 硬件
- 面板: 基于 LINGNITHM 3.2 的自制手台:
- Interface 0 = CDC 串口 (
/dev/ttyACM0, by-idusb-SparkFun_..._if00) → 触摸输入, 游戏直接读串口 - Interface 2 = HID 键盘 → AIR 传感器, 按键 = 小键盘 1–6 (
KP_1~KP_6)
- Interface 0 = CDC 串口 (
- GPU: Intel Iris Xe (核显) + NVIDIA RTX 3060 Laptop (独显, 需 PRIME offload 才能用上)
- 屏幕: 笔记本自带 1920x1080@165Hz (支持 60/165 切换)
1.2 软件
| 组件 | 版本 | 备注 |
|---|---|---|
| Wine | GE-Proton11-7 (wine 11.0 内核) | 通过 umu-run 启动 |
| umu-launcher | 1.4.3 | steamrt4 容器 |
| segatools | fufubot 1.0.4 定制版 | chusanhook.dll / chusanamhook.dll / chuniio-mux.dll 等 |
2. 部署流程 (从零到能玩)
2.1 游戏本体
参考 Evilleaker 的教程:
- 在 Windows 上安装并保证可以正常运行
- 对游戏文件打补丁绕过 1080P 和 120hz 检测
- 把游戏目录拷贝到 Linux 上
2.2 触摸面板 COM1 映射 (关键)
游戏直接读串口拿触摸数据, 所以要在 Wine prefix 里把 COM1 指向面板的串口设备。
预启动脚本 scripts/wine-com1-map.sh (Lutris 的 prelaunch_command):
#!/usr/bin/env bash
set -u
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
GAME_DIR="$(dirname "$SCRIPT_DIR")"
LOG="$GAME_DIR/com1-map.log"
WINEPREFIX="${WINEPREFIX:-$GAME_DIR/wine/pfx}"
PORTS="${CHUNI_COM_PORTS:-1}"
log() { printf '%s [com1-map] %s\n' "$(date '+%F %T')" "$*" >>"$LOG"; }
DEV="${CHUNI_COM_DEV:-}"
if [ -z "$DEV" ]; then
for candidate in \
$(ls -1 /dev/serial/by-id/* 2>/dev/null | head -n1) \
$(ls -1 /dev/ttyUSB* 2>/dev/null | head -n1) \
$(ls -1 /dev/ttyACM* 2>/dev/null | head -n1) \
$(ls -1 /dev/ttyS[0-9]* 2>/dev/null | head -n1) ; do
if [ -n "$candidate" ] && [ -e "$candidate" ]; then DEV="$candidate"; break; fi
done
fi
if [ -z "$DEV" ]; then log "WARN 未找到串口设备,游戏继续启动"; exit 0; fi
DOSDEV="$WINEPREFIX/dosdevices"
[ -d "$DOSDEV" ] || DOSDEV="$GAME_DIR/wine/dosdevices"
[ -d "$DOSDEV" ] || { log "ERROR 找不到 dosdevices"; exit 0; }
if [ ! -r "$DEV" ] || [ ! -w "$DEV" ]; then
log "WARN $DEV 不可读写(请加入 uucp 组并重新登录)"
fi
for p in $PORTS; do
link="$DOSDEV/com$p"
if [ -e "$link" ] && [ ! -L "$link" ]; then log "SKIP com$p 非符号链接"; continue; fi
rm -f "$link"; ln -s "$DEV" "$link"
if [ -L "$link" ]; then log "OK com$p -> $DEV"; else log "ERROR 创建 $link 失败"; fi
done
exit 0注: 面板不在时脚本会 回退到
/dev/ttyS0(主板自带串口), 游戏会打开一个滚木串口导致 3100 检测不到控制器错误
2.3 Lutris 配置
~/.local/share/lutris/games/chunithm.yml:
game:
exe: /path/to/Chunithm/bin/start.bat
prefix: /path/to/Chunithm/wine/pfx
working_dir: /path/to/Chunithm/bin
system:
env:
PROTON_USE_WINED3D: "1" # DXVK 笔者尝试了很久依然会崩
__NV_PRIME_RENDER_OFFLOAD: "1" # 独显
__GLX_VENDOR_LIBRARY_NAME: "nvidia" # 独显
MANGOHUD_CONFIG: fps_limit=120 # 锁 120fps
mangohud: true
prelaunch_command: /path/to/Chunithm/scripts/wine-com1-map.sh
prelaunch_wait: true
pulse_latency: true
wine:
overrides:
d3d8: b
d3d9: b
d3d10core: b
d3d11: b
d3d12: b
d3d12core: b
dxgi: b
winmm: n,b
version: GE-Proton11-7-x86_643. 按键链路原理
flowchart LR
subgraph AIR["AIR 传感器 通路"]
A1["面板 AIR 传感器"] -->|HID| A2["Linux input"]
A2 --> A3["X11"]
A3 --> A4["Wine (X11DRV)"]
A4 --> A5["GetAsyncKeyState(0x61..0x66)"]
end
subgraph GAME["游戏进程 (chusanApp)"]
G1["游戏"] --> G2["chusanhook.dll"]
G2 --> G3["chuniio-mux.dll"]
G3 --> G4["chuniio.dll"]
end
G4 -. "每帧轮询" .-> A5
subgraph TOUCH["触摸 通路"]
T1["触摸"] -->|CDC 串口| T2["/dev/ttyACM0"]
T2 -->|符号链接| T3["Wine COM1"]
T3 --> T4["游戏直接读串口"]
end
- AIR 轮询:
chuniio.dll每帧调用GetAsyncKeyState(vk_ir[i]), 不是消息。所以:- 按键必须进入 Wine 的键盘状态 (窗口有焦点时才会更新)
- NumLock 必须开: 否则小键盘 1–6 的 vkey 不是
0x61–0x66而是方向键 (VK_END等) [io3] ir语义 (segatools 源码chuniio/config.c):ir=0: 使用[ir]段的 6 个独立键ir=0x20: 空格模拟 AIR
4. 踩坑全记录
4.1 最大的坑: Wine 的 INI 解析器吞掉中文注释的下一行
症状:
- AIR 传感器按了没反应
- 但按空格反而能触发 AIR
根因:
AI 排错时在 segatools.ini 里写一行中文注释 (UTF-8 多字节):
; 0 = 使用下方 [ir] 的独立 AIR 键位 (LINGNITHM 面板 AIR 走 HID 键盘)
ir=0
Wine 的 GetPrivateProfileIntW 解析器会把中文注释的下一行 (ir=0) 整行吞掉,
于是游戏读不到 ir, 回退到**默认值 0x20 (空格) ** → 进入”空格模拟 AIR”模式:
- 空格能触发 AIR (虚拟手位置扫描)
- 小键盘/面板 AIR 全都不响应
结论:
segatools.ini 请只用 ASCII (英文) 注释。 中文注释在 Windows 下没问题 (Windows 的 INI 解析器行为不同) , 但在 Wine 下会吞掉下一行配置。
4.2 游戏默认跑在核显导致帧数低
Wine 默认跑在 Intel 核显上。可以用 glxinfo 验证:
# Intel
glxinfo -B | grep "OpenGL renderer" # → Mesa Intel(R) Iris(R) Xe Graphics
# NVIDIA
__NV_PRIME_RENDER_OFFLOAD=1 __GLX_VENDOR_LIBRARY_NAME=nvidia \
glxinfo -B | grep "OpenGL renderer" # → NVIDIA GeForce RTX 3060 Laptop GPU
把这两个变量写进 Lutris 的 env 即可 (mangohud 里能看到 NVIDIA 的占用率) 。
4.3 DXVK 启动白屏后静默退出
笔者为了性能试过把渲染从 wined3d 换成 DXVK:
- DXVK 初始化成功 (日志能看到
Creating device: NVIDIA GeForce RTX 3060、Setting display mode: 1920x1080@120、Present mode: FIFO) - 但游戏在交换链创建完成后立刻静默退出, 只能观测到白屏一闪就消失
结论: 这个游戏 + GE-Proton11-7 + DXVK 3.1 的组合下 DXVK 不可用, 只能用 wined3d。
4.5 wined3d 性能与 120fps 锁定
- wined3d 虽然是 OpenGL 翻译层, 但在 RTX 3060 上将将够用
- 音游的判定与帧挂钩, 需要稳定 120fps (游戏内是 120fps 模式)
- 由于笔记本屏幕只有 60/165Hz 两档 (没有 120Hz 模式) , 用 mangohud 的帧率限制器锁 120:
system:
env:
MANGOHUD_CONFIG: fps_limit=120
5. 附录
5.1 start.bat 内容 (参考)
@echo off
set OPENSSL_ia32cap=:~0x20000000
pushd %~dp0
taskkill /f /im amdaemon.exe > nul 2>&1
start /min inject_x64.exe -d -k chusanamhook.dll amdaemon.exe -f -c config_common.json ...
inject_x86.exe -d -k chusanhook.dll -k duolinguo.dll chusanApp.exe
taskkill /f /im amdaemon.exe > nul 2>&1
echo Game processes have terminated
pause5.2 坑合集
| # | 症状 | 根因 | 修复 |
|---|---|---|---|
| 1 | AIR 全无反应、空格却能触发 | Wine 吞掉中文注释的下一行 → ir 回退默认值 0x20 | 注释改 ASCII |
| 2 | 键盘没反应 | 按键进了控制台窗口 (焦点问题) | 点游戏窗口 / 全屏 |
| 3 | 帧数 60、GPU 20% | 跑在核显上 | PRIME offload 环境变量 |
| 4 | DXVK 白屏即崩 | DXVK 3.1 与游戏不兼容 | 用 wined3d |
| 5 | Lutris 启动即停 | game-paths.json 残留 | 清空该文件 |
| 6 | 触摸失效 | 面板 USB 掉线 / COM1 映射错误 | 重插面板 |
| 7 | 帧率浮动 (60/165) | vsync 跟随屏幕刷新率 | mangohud fps_limit=120 |
| 8 | 启动慢 (3 分钟+) | 正常模式首次加载曲库数据库 | 属正常, 等它加载完 |
本文档由排错过程中的实测数据整理, 所有结论均在 Arch + KDE Wayland + GE-Proton11-7 环境验证。
6. 结语
就这样,笔者的大学时光被出勤打舞萌和中二节奏毁了。
BTW I use Arch.
喜欢的话,留下你的评论吧~