Running roms in an emulator can be a very nostalgic experience and something you want to share with the next generation or with friends.
Many of the better emulated games for older systems are single player.
Running multiple copies of an old single player game can make for a very enjoyable experience.
The Nucleus Co-Op project is fantastic at making games allow for couch-play, splitscreen, etc, for games that didn't design that into the PC versions of the game.
Maybe there will be a game guide + plugin for Nucleus Co-op at some point made specifically for retroarch. For now I am using some of the debugging tools it comes with to get retroarch to allow multiple instances all with focus and a separate controller for each.
https://www.retroarch.com/?page=platforms
Download and install for Windows.
Or use chocolatey to install choco install retroarch
For this tutorial we are installing to
C:/tools/RetroArch-Win64
Install a core such as for n64 or for gba.
- Nintendo - Nintendo 64 (Mupen64Plus-Next)
- Nintendo - Game Boy Advance (mGBA)
Get a rom from the internet for a game you or your family owns.
Put it in a predictable folder on your computer.
Create duplicates of the rom for each person that will be playing the single player game simultaneously.
Such as:
SinglePlayerGame.n64 (downloaded into your C:/roms/n64 folder)
cp SinglePlayerGame.n64 Alice-controller1-spg.n64
cp SinglePlayerGame.n64 Bob-controller2-spg.n64
cp SinglePlayerGame.n64 Charlie-controller3-spg.n64
At some point this can probably be done directly by loading an additional config file... for now I change it thru the UI.
Context: Retroarch > Settings > Saving
Increment Save State Index Automatically
ON
Auto Save State
ON
Load Save State Automatically
ON
Save State Thumbnails
ON
https://www.autohotkey.com/download/
Download and install for Windows.
Or use chocolatey to install choco install autohotkey.install
AHK in this case is going to be used to toggle the WindowStyle to show the WindowTitle + Border or not.
Here is the script to do it when <Win> + W
is pressed on the keyboard.
; FWT - Fullscreen window toggle
; https://autohotkey.com/boards/viewtopic.php?p=123166#p123166
FWT(hwnd:="") {
static MONITOR_DEFAULTTONEAREST := 0x00000002
static WS_CAPTION := 0x00C00000
static WS_SIZEBOX := 0x00040000
static WindowStyle := WS_CAPTION|WS_SIZEBOX
static A := []
if (!hwnd) ; If no window handle is supplied, use the window under the mouse
MouseGetPos,,, hwnd
Win := "ahk_id " hwnd ; Store WinTitle
WinGet, S, Style, % Win ; Get window style
if (S & WindowStyle) { ; If not borderless
A[Win, "Style"] := S & WindowStyle ; Store existing style
; WinGet, IsMaxed, MinMax, % Win ; Get/store whether the window is maximized
; if (A[Win, "Maxed"] := IsMaxed = 1 ? true : false)
; WinRestore, % Win
; WinGetPos, X, Y, W, H, % Win ; Store window size/location
; A[Win, "X"] := X, A[Win, "Y"] := Y, A[Win, "W"] := W, A[Win, "H"] := H
WinSet, Style, % -WindowStyle, % Win ; Remove borders
; hMon := DllCall("User32\MonitorFromWindow", "Ptr", hwnd, "UInt", MONITOR_DEFAULTTONEAREST)
; VarSetCapacity(monInfo, 40), NumPut(40, monInfo, 0, "UInt")
; DllCall("User32\GetMonitorInfo", "Ptr", hMon, "Ptr", &monInfo)
; WinMove, % Win,, monLeft := NumGet(monInfo, 4, "Int") ; Move and resize window
; , monTop := NumGet(monInfo, 8, "Int")
; , (monRight := NumGet(monInfo, 12, "Int")) - monLeft
; , (monBottom := NumGet(monInfo, 16, "Int")) - monTop
}
else if A[Win] { ; If borderless
WinSet, Style, % "+" A[Win].Style, % Win ; Reapply borders
; WinMove, % Win,, A[Win].X, A[Win].Y, A[Win].W, A[Win].H ; Return to original position
; if (A[Win].Maxed) ; Maximize if required
; WinMaximize, % Win
A.Delete(Win)
}
}
#w::FWT(WinExist("A")) ; Win+W to fullscreen the active window
!^w::FWT() ; Ctrl+Alt+W to fullscreen the window under the mouse
Save the above script into borderless.ahk
and double click on it. It now shows up in the system tray.
https://nucleus-coop.github.io/docs/protoinput/
Download and install Nucleus Coop and you should find a copy of ProtoInputHost.exe on your machine.
For this tutorial it is installed into
C:\nucleus\NucleusCo-op\ProtoInputHost.exe
While retroarch is closed, let's turn off the menu bar in the retroarch windowed mode in the retoarch.cfg
file:
ui_menubar_enable = "false"
This can probably be done with a custom config getting loaded at runtime instead of putting some many copies of the entire folder... But I didn't know what things would have issues when running multiple copies... if there were any shared resources, etc or if it would stomp on some setting if I exited the programs out in a different order... So here goes.
cp C:/tools/RetroArch-Win64 C:/tools/RetroArch-Win64-1
cp C:/tools/RetroArch-Win64 C:/tools/RetroArch-Win64-2
cp C:/tools/RetroArch-Win64 C:/tools/RetroArch-Win64-3
Create some additional shortcuts for the retroarch.exe
's in each of the new folders you made.
e.g.
C:/tools/"retroarch.exe - alice-controller1".lnk # references RetroArch-Win64-1
C:/tools/"retroarch.exe - bob-controller2".lnk # references RetroArch-Win64-2
C:/tools/"retroarch.exe - charlie-controller3".lnk # references RetroArch-Win64-3
Now modify 2 more settings in each of the retroarch.cfg
files in each of the program folders.
# In RetroArch-Win64-1 aka alice-controller1 folder
input_player1_joypad_index = "1"
input_player2_joypad_index = "2"
input_player3_joypad_index = "3"
# In RetroArch-Win64-2 aka alice-controller2 folder
input_player1_joypad_index = "2" # Note, swapped with player2
input_player2_joypad_index = "1"
input_player3_joypad_index = "3"
# In RetroArch-Win64-2 aka alice-controller3 folder
input_player1_joypad_index = "3" # Note, swapped with player3
input_player2_joypad_index = "2"
input_player3_joypad_index = "1"
Now open 1 copy of each retroarch and turn on 3 controllers.
Open the rom named c:/roms/n64/Alice-controller1-spg.n64
in the first instance of retroarch.
Open the rom named c:/roms/n64/Bob-controller2-spg.n64
in the second instance of retroarch.
Open the rom named c:/roms/n64/Charlie-controller1-spg.n64
in the third instance of retoarch.
As each game loads, it freezes when the program loses focus. Also each windowed game has a title bar (but no menu bar).
Now open C:\nucleus\NucleusCo-op\ProtoInputHost.exe
(or whereever you installed Nucleus Co-op.
Search for programs named retro
. Select the three instances and click add.
You can leave the settings on default, but I like to see the cursor, so I change:
Context: Proto Input
Launch
Lock input with the End key
(unchecked)
Hooks
Cursor Visibility
(unchecked)
Clip Cursor
(unchecked)
Finally, click: Proto Input > Launch > Inject Instances (button)
Now each window can be repositioned manually and resized. After each window is in the right place, click one then press
<Win> + W
.
Now you have an awesome way to each kid in the room to play on the TV without needing N computers turned on and setup.