操作方式¶
输入来自第一个 SDL3 手柄、键盘和鼠标,三者合并为一个 Switch 控制器(runtime/input_win.c)。按钮采用“或”逻辑;每个摇杆取偏移量较大的输入源。仅当游戏窗口处于前台时,按键和鼠标按钮才生效。TOTK_INPUT=none 会同时禁用两者(用于自动化运行)。TOTK_* 设置也可以在 totk.exe 旁边的 totk.ini 中设置(input = none、motion = 0、rumble = 0);环境变量会覆盖配置文件。TOTK_RUMBLE_STRENGTH 是以百分比表示的震动强度(0 到 300,默认 130;0 与 rumble = 0 相同)。TOTK_RUMBLE_CURVE 是在强度之前应用于振幅的指数(0.2 到 1.5,默认 0.6;数值越低,弱脉冲越强,1 为线性)。TOTK_RUMBLE_TRIGGERS=1 还会驱动 Xbox 手柄的扳机震动马达。
TOTK_PAD_LAYOUT(pad_layout,即控制选项卡中的“按钮布局”行,实时生效)用于选择哪个正面按钮是 Switch 的 A 键:
nintendo:按位置对应,与 Switch 上一样(见下表)。xbox:南 A、东 B、西 X、北 Y,按照 Xbox 手柄的标签;在 PlayStation 手柄上,X 键为 A、圆圈为 B、方块为 X、三角为 Y。auto(默认):对于 SDL 报告其东侧按钮标签为 A 的手柄(Switch Pro Controller、任天堂布局手柄)使用nintendo,其他手柄使用xbox。
日志会显示当前生效的布局(input: gamepad layout ...);菜单会在“Automatic”下显示它。无论哪种布局,游戏内的按钮提示始终显示 Switch 按键字母。
| Switch | 手柄(按位置,Nintendo 布局) | 键盘和鼠标 | 游戏世界中的动作 |
|---|---|---|---|
| 左摇杆 | 左摇杆 | W A S D | 移动 |
| 右摇杆 | 右摇杆 | 鼠标;方向键作为第二输入源 | 视角 |
| Y | 西 | 鼠标左键 | 攻击 |
| ZL | 左扳机(超过 50%) | 鼠标右键、Z | 盾牌、锁定 |
| ZR | 右扳机(超过 50%) | F、X | 弓 |
| X | 北 | 空格 | 跳跃 |
| B | 南 | 左 Shift | 奔跑、取消 |
| A | 东 | E | 互动、拾取 |
| L | 左肩键 | Q | 能力 |
| R | 右肩键 | R | 投掷武器 |
| 左摇杆按下 | 左摇杆按下 | 左 Ctrl | 蹲下 |
| 右摇杆按下 | 右摇杆按下 | C | 第一人称视角 |
| 十字键左、上、右、下 | 十字键 | 1 2 3 4 | 快捷选择 |
| Plus | Start | Tab | 菜单、物品栏 |
| Minus | Back | M | 地图 |
Esc 在游戏中未绑定;它打开设置菜单并释放鼠标光标(见鼠标视角)。Z 和 X 分别替代 ZL 和 ZR,这样菜单翻页可以用两个相邻按键完成;菜单选项卡(L、R)对应 Q 和 R。鼠标滚轮未绑定。这些绑定是 runtime/input_map.c 中 input_map 的表格:键位(平台无关的按键 ID)和每种布局各一张手柄表格(按位置的手柄输入);runtime/input_win.c 负责转换 Win32 虚拟按键和 SDL 按钮。
窗口按键¶
| 按键 | 手柄 | 动作 |
|---|---|---|
| F1 或 Esc | Minus 和 Plus 同时按下 | 打开或关闭设置菜单;菜单打开期间游戏收不到任何输入 |
| F10 | 性能覆盖层:关闭、帧率、完整面板 | |
| F11 | 切换无边框全屏,保存到 totk.ini |
Minus+Plus 组合键永远不会传给游戏。在菜单中,方向键、十字键或左摇杆移动,Enter 或 A 选择,Q 和 E 或 L 和 R 切换选项卡,Esc 或 B 返回(使用 Switch 按钮名称,如上表所示)。
重新映射¶
设置菜单的“控制”选项卡在按钮布局下方列出了每个 Switch 按钮以及按键驱动的八个摇杆方向(移动和视角),每个都有两个按键单元格和一个控制器单元格。选择一个单元格,按 A 或 Enter,然后按下新的按键、鼠标按钮或控制器按钮;Esc 或五秒无按下则取消,控制器按钮会取消按键单元格。Delete、Backspace 或 X 清除所选单元格。已被其他动作使用的按键会移动到新动作上(描述会显示该动作离开了哪个按键);控制器按钮则与它所替换的按钮交换。重新映射后的控制器按钮是物理位置的:此后正面按钮(A B X Y)在两种布局中都保持其物理位置,直到这些按钮被恢复为当前布局所使用的位置,或选择“Reset all buttons”。F1、F8、F10、F11 和 Esc 不能被绑定(菜单、飞行记录器和窗口保留它们)。标点按键按美式键盘上的位置命名;菜单显示当前键盘布局在该位置产生的字符。
该选项卡会写入 totk.ini 行,每个 Switch 按钮或摇杆方向一行:bind_<button> = <entry>, <entry>, ...。按钮为 A B X Y L R ZL ZR PLUS MINUS LEFT UP RIGHT DOWN LCLICK RCLICK,或摇杆方向 LSTICK_LEFT LSTICK_UP LSTICK_RIGHT LSTICK_DOWN(移动,默认 W A S D)和 RSTICK_...(视角,方向键)。条目为 pad:<name> 或 key:<name>:
- 手柄名称:
south east west north l r zl zr start back lstick rstick dpad_left dpad_up dpad_right dpad_down(zl、zr是扳机) - 按键名称:
a到z、0到9、f2到f7、f9、f12、num0到num9、space tab enter backspace lshift rshift lctrl rctrl lalt capslock insert delete home end pageup pagedown up down left right、num_add num_sub num_mul num_div num_decimal、minus equals lbracket rbracket semicolon apostrophe comma period slash backslash grave、mouse_l mouse_r mouse_m mouse_x1 mouse_x2 key:default和pad:default保持该部分的默认值(pad:default是每种布局各自的按钮)。none让该按钮保持未绑定。
一行会替换该按钮的所有默认值,包括手柄和键盘,因此请列出你仍然想要的按键或使用 key:default。手柄名称是物理位置,因此一行在两种布局中含义相同,并会替换该布局中该 Switch 按钮对应的按钮。摇杆方向只接受按键:控制器摇杆和鼠标视角始终有效。没有行的按钮保持上表中的默认值。名称不区分大小写。无效条目会记录一行 input: bind ... 日志并被跳过;没有有效条目的行不会改变任何内容。TOTK_BIND_<button> 环境变量的工作方式与其他设置相同。更改后的行会立即生效(runtime/input_win.c 会在下一次轮询时重新构建表格)。
对于会报告其正面按键互换(A/B 和 X/Y,某些 GuliKit 型号如此)的手柄,可通过以下方式修复:
bind_A = pad:south, key:E
bind_B = pad:east, key:lshift
bind_X = pad:west, key:space
bind_Y = pad:north, key:mouse_l
鼠标视角¶
鼠标移动(原始输入)会变为右摇杆偏移。每呈现一帧时,取自上一帧以来移动的计数,除以帧时间,并将偏移设置为满量程的 counts per second * TOTK_MOUSE_SENS / 3000,在该帧期间保持,因此转向速率不依赖于帧率。这不是 mouselook:游戏的摇杆曲线和死区仍然生效,因此非常缓慢的移动不会产生任何效果,而快速甩动会达到饱和。鼠标偏移与手柄和方向键按照“较大偏移优先”规则竞争。
TOTK_MOUSE_SENS(0 到 10,默认 1;数值越高转向越快,0 会关闭鼠标视角和光标捕获)。当窗口是前台窗口时,光标会被隐藏并限制在客户区域内。在失去焦点、最小化、F11 切换窗口、调整大小或移动窗口循环期间,以及文本输入打开时,光标会被释放。按 Esc 可手动释放:光标显示,鼠标视角和鼠标按键停止,窗口可以移动、最小化或关闭。在客户区域内单击鼠标会重新捕获;该点击不会传递到游戏。通过单击标题栏或边框激活窗口不会捕获光标,因此可以立即拖动或关闭窗口;Alt+Tab 或点击客户区域则会像之前一样捕获。TOTK_INPUT=none 也会禁用捕获。
摇杆方向位(StickLLeft 到 StickRDown)根据摇杆在 50% 偏移时的状态得出。之后插入的手柄会在一秒内被识别;若未连接任何手柄,日志会显示 input: no gamepad。
脚本化输入¶
TOTK_INPUT_SCRIPT=<file> 重放按键按下事件。它与真实输入进行 OR 合并,并且在 TOTK_INPUT=none 下仍然生效。每行一个事件,# 表示注释开始:
<frame> <button> [hold_frames] # A B X Y L R ZL ZR PLUS MINUS LEFT UP RIGHT DOWN LCLICK RCLICK; hold defaults to 4
<frame> LSTICK|RSTICK <x> <y> [hold_frames] # -32767..32767, up is +y
@<ms> <button> [hold_ms] # timed on the world clock
@<ms> LSTICK|RSTICK <x> <y> [hold_ms]
<frame> 计算自第一帧以来游戏时间的 60 Hz 刻度(呈现帧为 60 fps),因此无论帧率上限如何,标题菜单都会在同一游戏时间收到按键。@<ms> 计算世界时钟的毫秒数:即自第一次加载存档结束(玩家离开标题画面的起点)以来推进的游戏时间,因此无论帧率或加载时长如何,计时事件都会落在相同的游戏时间。后续的加载(例如快速旅行)仍会使之后的事件发生偏移。在包含计时行的脚本中,当世界时钟启动时,未计时的事件会停止,因为每次运行时加载都在不同的 tick 处结束。每个事件记录一次(input: script frame N tick T: A)。tools/input/load_save.txt 从标题画面加载第一个存档。
TOTK_INPUT_RECORD=<file>(totk.ini 中的 input_record,或菜单中的 Input recording)将合并后的输入写入相同格式,每个按键按下和每个摇杆段各占一行:世界时钟开始前的事件按 tick 记录,其余事件按计时记录;当世界时钟启动时,正在按下的按键或摇杆会在该处截断,并作为计时事件继续记录。该文件可作为脚本重放,因此可用作附加到 bug 报告的复现用例。
RenderDoc 捕获(已阻止)¶
TOTK_RDOC=<frame>[,...](runtime/rdoc_win.c;TOTK_RDOC_DIR、TOTK_RDOC_DLL)会在 vkCreateInstance 之前加载 RenderDoc。RenderDoc 会隐藏 VK_EXT_external_memory_host,而后端在导入 guest pool 时需要该扩展(runtime/vk_memory.c),因此在 RenderDoc 下创建设备会失败。要进行捕获,首先需要基于拷贝(copy-based)的池回退方案。
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 to/totk-pc-recomp