一台电脑两台手柄?任意 PC 游戏双人分屏的完整指南
【免费下载链接】UniversalSplitScreenSplit screen multiplayer for any game with multiple keyboards, mice and controllers.项目地址: https://gitcode.com/gh_mirrors/un/UniversalSplitScreen
Universal Split Screen 是一个开源的 PC 游戏分屏工具:一台电脑接上两套键盘鼠标或多只手柄,就能让本来只有单人模式的 PC 游戏实现本地多人同屏对战。它按玩家数量把游戏画面切块,把每套输入设备分别"喂"给对应的玩家区域,整个过程对游戏本身透明。
三步完成安装与编译
先克隆源码:
git clone https://gitcode.com/gh_mirrors/un/UniversalSplitScreen用 Visual Studio 打开 UniversalSplitScreen.sln 后,按下面的顺序编译各组件(各项目的后构建脚本会自动改名并复制到指定位置):
- 主程序:UniversalSplitScreen,用 x86 平台编译,产出主应用;
- HooksCPP:x86 与 x64 各编一次,得到 HooksCPP32.dll 与 HooksCPP64.dll,放到主程序目录;
- InjectorLoader:x86 与 x64 各编一次,得到 IJx86.exe 与 IJx64.exe,同样放进主程序目录;
- SourceEngineUnlocker:x86 编译后,把 SourceEngineUnlocker.dll 复制到主程序目录,供 Source 引擎游戏使用。
也可以直接用 Visual Studio 的批量构建一次编完。配置如何生效:程序启动时会扫描程序目录下 Config 中的全部 JSON 文件,每个文件对应一套游戏选项,加载进界面上方的下拉框。想支持自己的游戏,照着现有格式新建一个 JSON、填好OptionsName即可被识别。
预置游戏与分屏效果
Config 目录已内置 13 份经过调优的预设,按类型大致可以这样分:
| 类别 | 预置游戏 |
|---|---|
| 沙盒建造 | Minecraft(1.14.3 与 Alternate 两套)、Terraria |
| 生存冒险 | Don't Starve Together、Stardew Valley、Starbound |
| 动作射击 | Borderlands 2、Nuclear Throne |
| 策略模拟 | Factorio、Prison Architect |
| 引擎通用 | Source Engine、GoldSrc Engine |
| 其他 | Rift |
Source Engine 与 GoldSrc 这两份是"通杀"配置,同引擎的《半条命 2》《Garry's Mod》一类游戏都可以直接套用。分屏时每个玩家拿到独立的操作视角与输入通道,窗口被均分或按人数切块,互不抢占。
工作原理简述
整条链路只有三个角色,各司其职:
- 输入钩子(HooksCPP):一个 C++ 动态库,注入游戏进程后接管游戏读取键位、鼠标位置的 Windows 系统调用。游戏每次"问键盘",它都先过一道筛子,让各玩家只看到自己那部分输入。
- 进程注入器(InjectorLoader):把钩子库装进目标游戏进程。这里要解释一下"进程注入":Windows 下往另一个程序里塞代码的唯一常规手段,就是先把代码写成 DLL 再让它被加载,注入器做的就是这件事,32 位与 64 位游戏各有一把钥匙。
- 窗口管理(主程序内的 SplitScreenManager):按玩家数量把游戏窗口切成若干区域,并持续修正边界,保证玩家 1 的键位不会误发给玩家 2 的区域。
输入本身走的是 Raw Input——Windows 提供的原始输入接口,能绕过系统级的消息轮询直接拿到设备的原始信号,延迟低且与游戏自身的输入方式兼容。
配置参数调优清单
每个游戏预设都是一个 JSON 文件,常用参数分四组:
| 参数组 | 代表字段 | 作用 |
|---|---|---|
| 输入发送方式 | SendNormalKeyboardInput、SendNormalMouseInput、SendRawMouseInput、SendScrollwheel | 选择用普通消息、原始输入还是滚轮事件去"喂"游戏,多数游戏用普通模式即可 |
| 钩子开关 | Hook_GetAsyncKeyState、Hook_GetKeyState、Hook_GetForegroundWindow、Hook_FilterRawInput | 决定拦截哪些系统查询函数,按引擎逐个开关,Source 引擎一般全开 |
| 窗口行为 | RefreshWindowBoundsOnMouseClick、DrawMouse、SendWM_ACTIVATE | 控制是否随点击刷新窗口边界、是否绘制系统鼠标、切换时是否激活窗口 |
| 手柄 | Hook_XInput、Hook_DirectInput | 分别接管 XInput(Xbox 手柄)与 DirectInput 两套手柄接口 |
调优建议:
- 游戏保持窗口化或无边框模式运行,全屏独占下窗口管理手段全部失效;
- 分屏分辨率按显示器实际规格设置,切块过多会压低单侧帧率;
- 感觉输入有延迟时优先检查钩子开关是否与引擎匹配,而不是调系统设置;
- 多显示器时建议整块屏幕分给游戏,避免跨屏切割带来的错位;
- 分屏前关掉吃 CPU 的后台程序,给每个玩家的输入轮询留足预算。
常见问题自查
| 现象 | 可能原因 | 解决办法 |
|---|---|---|
| 第二套输入完全没有反应 | 游戏以管理员运行而工具没有 | 两边权限保持一致,都用管理员身份启动 |
| 分屏错位、鼠标飘到别人区域 | 游戏处于独占全屏 | 改为窗口化或无边框窗口再分屏 |
| 手柄识别不到 | XInput / DirectInput 钩子未开启 | 按实际手柄接口打开Hook_XInput或Hook_DirectInput |
| 配置文件不生效 | JSON 格式错误或缺少OptionsName | 对照现有预设检查字段名与引号,重启程序重新加载 |
项目结构与参与方式
源码分成几个职责清晰的块:
| 目录 / 组件 | 职责 |
|---|---|
| Core | 主程序协调:配置加载、分屏状态、更新检查 |
| RawInput | 基于原始输入接口采集键盘、鼠标、手柄的原始数据 |
| SendInput | 把整理好的输入以系统消息形式发回给游戏 |
| UI | 操作界面:选项下拉框、复选框、更新弹窗 |
| Config | 全部游戏预设 JSON |
| HooksCPP / InjectorLoader / SourceEngineUnlocker | 输入钩子、进程注入器、引擎解锁,均为 C++ 组件,各有 x86 与 x64 版本 |
项目采用 MIT 许可证,参与方式不限:提交 issue 反馈问题、修改或扩展代码、为新游戏编写 JSON 预设、翻译文档都可以。改动主程序时注意编译平台是 x86,钩子与注入器则两个平台都要出。
Universal Split Screen 的价值在于把"PC 游戏没有本地多人"这件事变成了纯工程问题。挑一份现成预设跑通你的第一款游戏,是上手的最佳起点。
【免费下载链接】UniversalSplitScreenSplit screen multiplayer for any game with multiple keyboards, mice and controllers.项目地址: https://gitcode.com/gh_mirrors/un/UniversalSplitScreen
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考