Ilyaki / ProtoInput

Proto Input enables split screen on PC games by hooking Windows functions and redirecting input from multiple keyboards/mice/controllers
MIT License
45 stars 11 forks source link
cpp hooks windows

Proto Input

Proto Input is a set of libraries that enables split screen on PC games by hooking Windows functions and redirecting input from multiple keyboards/mice/controllers. ProtoInput contains many improvements over my previous works on Universal Split Screen and ZeroFox\'s Nucleus Coop Mod. The project is in a modular form so it can be easily used in any project with its C function API.

Proto Input is now included as part of Nucleus Co-Op. This is the best way to use Proto Input, as it is fully scriptable.

The main highlights are:

In-game GUI control interface

The GUI interface can be opened by pressing Right Ctrl + Right Alt + 1/2/3/4... (depending on the instance index). The GUI lets you enable/configure hooks, change input settings, Windows message filters, etc, all without restarting the game, so you can quickly setup a profile.

Proto Input Hooks GUI

Proto Input Host

Proto Input Host is a GUI tool that uses the API interface to set up input and hooks for processes. You can effectively think of this as a souped up Universal Split Screen.

Proto Input Host GUI

Smooth input

Unlike my previous works, ProtoInput performs all input redirection from within the target process using hooks. This gives much smoother input, and better compatibility with games. Additionally I\'ve completely re-written most of the hooks. You should now be able to enable almost all hooks and have input working out of the box.

API interface

ProtoInput is modular by design so it can be used in another project. An external project can inject the ProtoInput hooks into a process by calling the functions in protoloader.h, e.g.

auto path = LR"(C:\WINDOWS\system32\notepad.exe)";
unsigned long pid;

// Use startup injection to create a process and inject the hooks
ProtoInstanceHandle instanceHandle = EasyHookInjectStartup(path, L"", 0, folderpath.c_str(), &pid);

// Let the hooks know it's the 1st index (So open the GUI with Right Ctrl + Right Alt + 1)
SetupState(instanceHandle, 1);

// Install the RegisterRawInput hook
InstallHook(instanceHandle, RegisterRawInputHookID);

// Tell the hooks to send mouse move, button, etc messages
SetupMessagesToSend(instanceHandle, true, true, true, true);

// Start a loop that sends WM_ACTIVATE, WM_ACTIVATEAPP, etc every 5 milliseconds
StartFocusMessageLoop(instanceHandle, 5, true, true, true, true, true);

// The processes was created in a suspended state, so now wake it up
WakeUpProcess(instanceHandle);

The API interface is C-style, so you can call it from almost any language. Some additional functionality (e.g. input locking) is provided in ProtoInputUtil, separate from the hooks.

Some minor things