Skip to content

Commit

Permalink
WIP netplay
Browse files Browse the repository at this point in the history
  • Loading branch information
Rosalie241 committed Dec 22, 2024
1 parent cc75ce5 commit 62bfe92
Show file tree
Hide file tree
Showing 42 changed files with 2,450 additions and 188 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
- name: Install Packages
run: |
sudo add-apt-repository ppa:okirby/qt6-backports --yes
sudo apt-get -y install cmake ninja-build libhidapi-dev libsamplerate0-dev libspeex-dev libminizip-dev libsdl2-dev libfreetype6-dev libgl1-mesa-dev libglu1-mesa-dev pkg-config zlib1g-dev binutils-dev libspeexdsp-dev qt6-base-dev libqt6svg6-dev libvulkan-dev build-essential nasm git zip appstream
sudo apt-get -y install cmake ninja-build libhidapi-dev libsamplerate0-dev libspeex-dev libminizip-dev libsdl2-dev libsdl2-net-dev libfreetype6-dev libgl1-mesa-dev libglu1-mesa-dev pkg-config zlib1g-dev binutils-dev libspeexdsp-dev qt6-base-dev libqt6svg6-dev libqt6websockets6-dev libvulkan-dev build-essential nasm git zip appstream
- name: Prepare Environment
run: |
echo "GIT_REVISION=$(git describe --tags --always)" >> $GITHUB_ENV
Expand Down Expand Up @@ -67,6 +67,7 @@ jobs:
mingw-w64-x86_64-freetype
mingw-w64-x86_64-libpng
mingw-w64-x86_64-SDL2
mingw-w64-x86_64-SDL2_net
mingw-w64-x86_64-qt6
mingw-w64-x86_64-SDL2
mingw-w64-x86_64-hidapi
Expand Down
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ option(UPDATER "Enables updater" ${WIN32})
option(APPIMAGE_UPDATER "Enables AppImage updater" OFF)
option(DISCORD_RPC "Enables Discord Rich Presence" ON)
option(DRAG_DROP "Enables drag and drop" ON)
option(NETPLAY "Enables netplay" ON)
option(VRU "Enables VRU support in RMG-Input" ON)
option(USE_CCACHE "Enables usage of ccache when ccache has been found" ON)
option(USE_LTO "Enables building with LTO/IPO when compiler supports it" ON)
Expand Down
3 changes: 2 additions & 1 deletion Source/3rdParty/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ ExternalProject_Add(mupen64plus-core
BUILD_COMMAND ${MAKE_CMD} all -f ${M64P_CORE_DIR}/projects/unix/Makefile
SRCDIR=${CMAKE_CURRENT_SOURCE_DIR}/mupen64plus-core/src
SUBDIR=${CMAKE_CURRENT_SOURCE_DIR}/mupen64plus-core/subprojects
OSD=0 NEW_DYNAREC=1 NO_ASM=$<BOOL:${NO_ASM}> KEYBINDINGS=0 ACCURATE_FPU=1 VULKAN=0
OSD=0 NEW_DYNAREC=1 NO_ASM=$<BOOL:${NO_ASM}>
KEYBINDINGS=0 ACCURATE_FPU=1 VULKAN=0 NETPLAY=$<BOOL:${NETPLAY}>
TARGET=${CORE_FILE} DEBUG=${MAKE_DEBUG}
CC=${MAKE_CC_COMPILER} CXX=${MAKE_CXX_COMPILER}
OPTFLAGS=${MAKE_OPTFLAGS}
Expand Down
7 changes: 7 additions & 0 deletions Source/RMG-Core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ if (DISCORD_RPC)
add_definitions(-DDISCORD_RPC)
endif(DISCORD_RPC)

if (NETPLAY)
list(APPEND RMG_CORE_SOURCES
Netplay.cpp
)
add_definitions(-DNETPLAY)
endif(NETPLAY)

if (PORTABLE_INSTALL)
add_definitions(-DPORTABLE_INSTALL)
endif(PORTABLE_INSTALL)
Expand Down
1 change: 1 addition & 0 deletions Source/RMG-Core/Core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "SaveState.hpp"
#include "RomHeader.hpp"
#include "Callback.hpp"
#include "Netplay.hpp"
#include "Plugins.hpp"
#include "Version.hpp"
#include "Cheats.hpp"
Expand Down
65 changes: 49 additions & 16 deletions Source/RMG-Core/Emulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "RomHeader.hpp"
#include "m64p/Api.hpp"
#include "Plugins.hpp"
#include "Netplay.hpp"
#include "Cheats.hpp"
#include "Error.hpp"
#include "Rom.hpp"
Expand Down Expand Up @@ -145,10 +146,12 @@ static void apply_pif_rom_settings(void)
// Exported Functions
//

bool CoreStartEmulation(std::filesystem::path n64rom, std::filesystem::path n64ddrom)
bool CoreStartEmulation(std::filesystem::path n64rom, std::filesystem::path n64ddrom,
std::string address, int port, int player)
{
std::string error;
m64p_error ret;
m64p_error m64p_ret;
bool netplay_ret = false;
CoreRomType type;

if (!CoreOpenRom(n64rom))
Expand Down Expand Up @@ -177,12 +180,16 @@ bool CoreStartEmulation(std::filesystem::path n64rom, std::filesystem::path n64d
return false;
}

if (!CoreApplyCheats())
// TODO: add support for cheats during netplay
if (!address.empty())
{
CoreDetachPlugins();
CoreApplyPluginSettings();
CoreCloseRom();
return false;
if (!CoreApplyCheats())
{
CoreDetachPlugins();
CoreApplyPluginSettings();
CoreCloseRom();
return false;
}
}

if (!CoreGetRomType(type))
Expand Down Expand Up @@ -213,12 +220,35 @@ bool CoreStartEmulation(std::filesystem::path n64rom, std::filesystem::path n64d
CoreDiscordRpcUpdate(true);
#endif // DISCORD_RPC

ret = m64p::Core.DoCommand(M64CMD_EXECUTE, 0, nullptr);
if (ret != M64ERR_SUCCESS)
#ifdef NETPLAY
if (!address.empty())
{
error = "CoreStartEmulation m64p::Core.DoCommand(M64CMD_EXECUTE) Failed: ";
error += m64p::Core.ErrorMessage(ret);
netplay_ret = CoreInitNetplay(address, port, player);
if (!netplay_ret)
{
m64p_ret = M64ERR_SYSTEM_FAIL;
}
}
#endif // NETPLAY

// only start emulation when initializing netplay
// is successful or if there's no netplay requested
if (address.empty() || netplay_ret)
{
m64p_ret = m64p::Core.DoCommand(M64CMD_EXECUTE, 0, nullptr);
if (m64p_ret != M64ERR_SUCCESS)
{
error = "CoreStartEmulation m64p::Core.DoCommand(M64CMD_EXECUTE) Failed: ";
error += m64p::Core.ErrorMessage(m64p_ret);
}
}

#ifdef NETPLAY
if (!address.empty() && netplay_ret)
{
CoreShutdownNetplay();
}
#endif // NETPLAY

CoreClearCheats();
CoreDetachPlugins();
Expand All @@ -234,12 +264,15 @@ bool CoreStartEmulation(std::filesystem::path n64rom, std::filesystem::path n64d
CoreDiscordRpcUpdate(false);
#endif // DISCORD_RPC

// we need to set the emulation error last,
// to prevent the other functions from
// overriding the emulation error
CoreSetError(error);
if (address.empty() || netplay_ret)
{
// we need to set the emulation error last,
// to prevent the other functions from
// overriding the emulation error
CoreSetError(error);
}

return ret == M64ERR_SUCCESS;
return m64p_ret == M64ERR_SUCCESS;
}

bool CoreStopEmulation(void)
Expand Down
2 changes: 1 addition & 1 deletion Source/RMG-Core/Emulation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ enum class CoreEmulationState
};

// starts emulation with given ROM
bool CoreStartEmulation(std::filesystem::path n64rom, std::filesystem::path n64ddrom);
bool CoreStartEmulation(std::filesystem::path n64rom, std::filesystem::path n64ddrom, std::string address = "", int port = -1, int player = -1);

// stops emulation
bool CoreStopEmulation(void);
Expand Down
102 changes: 102 additions & 0 deletions Source/RMG-Core/Netplay.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifdef _WIN32
#define _CRT_RAND_S
#include <cstdlib>
#endif // _WIN32
#include "Netplay.hpp"
#include "Error.hpp"
#include "m64p/Api.hpp"



//
// Local Variables
//

static bool l_HasInitNetplay = false;

//
// Exported Functions
//

bool CoreInitNetplay(std::string address, int port, int player)
{
std::string error;
m64p_error ret;
uint32_t id = 0;

// initialize random ID
while (id == 0)
{
#ifdef _WIN32
rand_s(&id);
#else
id = rand();
#endif
id &= ~0x7;
id |= player;
}

uint32_t version;
ret = m64p::Core.DoCommand(M64CMD_NETPLAY_GET_VERSION, 0x010001, &version);
if (ret != M64ERR_SUCCESS)
{
error = "CoreInitNetplay m64p::Core.DoCommand(M64CMD_NETPLAY_GET_VERSION) Failed: ";
error += m64p::Core.ErrorMessage(ret);
CoreSetError(error);
return false;
}

ret = m64p::Core.DoCommand(M64CMD_NETPLAY_INIT, port, (void*)address.c_str());
if (ret != M64ERR_SUCCESS)
{
error = "CoreInitNetplay m64p::Core.DoCommand(M64CMD_NETPLAY_INIT) Failed: ";
error += m64p::Core.ErrorMessage(ret);
CoreSetError(error);
return false;
}

ret = m64p::Core.DoCommand(M64CMD_NETPLAY_CONTROL_PLAYER, player, &id);
if (ret != M64ERR_SUCCESS)
{
error = "CoreInitNetplay m64p::Core.DoCommand(M64CMD_NETPLAY_CONTROL_PLAYER) Failed: ";
error += m64p::Core.ErrorMessage(ret);
CoreSetError(error);
CoreShutdownNetplay();
return false;
}

l_HasInitNetplay = true;
return true;
}

bool CoreHasInitNetplay(void)
{
return l_HasInitNetplay;
}

bool CoreShutdownNetplay(void)
{
std::string error;
m64p_error ret;

ret = m64p::Core.DoCommand(M64CMD_NETPLAY_CLOSE, 0, nullptr);
if (ret != M64ERR_SUCCESS)
{
error = "CoreShutdownNetplay m64p::Core.DoCommand(M64CMD_NETPLAY_CLOSE) Failed: ";
error += m64p::Core.ErrorMessage(ret);
CoreSetError(error);
return false;
}

l_HasInitNetplay = false;
return true;
}
24 changes: 24 additions & 0 deletions Source/RMG-Core/Netplay.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
* Copyright (C) 2020 Rosalie Wanders <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef CORE_NETPLAY_HPP
#define CORE_NETPLAY_HPP

#include <string>

// attempts to initialize netplay
bool CoreInitNetplay(std::string address, int port, int player);

// returns whether netplay has been initialized
bool CoreHasInitNetplay(void);

// attempts to shutdown netplay
bool CoreShutdownNetplay(void);

#endif // CORE_NETPLAY_HPP
9 changes: 9 additions & 0 deletions Source/RMG-Core/Settings/Settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ static std::vector<std::string> l_keyList;
//

#define SETTING_SECTION_GUI "Rosalie's Mupen GUI"
#define SETTING_SECTION_NETPLAY SETTING_SECTION_GUI " Netplay"
#define SETTING_SECTION_CORE SETTING_SECTION_GUI " Core"
#define SETTING_SECTION_OVERLAY SETTING_SECTION_CORE " Overlay"
#define SETTING_SECTION_KEYBIND SETTING_SECTION_GUI " KeyBindings"
Expand Down Expand Up @@ -158,6 +159,14 @@ static l_Setting get_setting(SettingsID settingId)
setting = {SETTING_SECTION_GUI, "Version", CoreGetVersion()};
break;

case SettingsID::Netplay_Nickname:
setting = {SETTING_SECTION_NETPLAY, "Nickname", "NetplayUser"};
break;

case SettingsID::Netplay_ServerJsonUrl:
setting = {SETTING_SECTION_NETPLAY, "ServerJsonUrl", "https://m64p.s3.amazonaws.com/servers.json"};
break;

case SettingsID::Core_GFX_Plugin:
setting = {SETTING_SECTION_CORE, "GFX_Plugin",
#ifdef _WIN32
Expand Down
4 changes: 4 additions & 0 deletions Source/RMG-Core/Settings/SettingsID.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ enum class SettingsID
GUI_DiscordRpc,
GUI_Version,

// Netplay Settings
Netplay_Nickname,
Netplay_ServerJsonUrl,

// Core Plugin Settings
Core_GFX_Plugin,
Core_AUDIO_Plugin,
Expand Down
23 changes: 23 additions & 0 deletions Source/RMG/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ if (DRAG_DROP)
add_definitions(-DDRAG_DROP)
endif(DRAG_DROP)

if (NETPLAY)
find_package(Qt6 COMPONENTS WebSockets REQUIRED)
add_definitions(-DNETPLAY)
endif(NETPLAY)

find_package(PkgConfig REQUIRED)
pkg_check_modules(SDL2 REQUIRED sdl2)

Expand Down Expand Up @@ -82,6 +87,20 @@ if (UPDATER)
)
endif(UPDATER)

if (NETPLAY)
list(APPEND RMG_SOURCES
UserInterface/Dialog/Netplay/NetplayCommon.cpp
UserInterface/Dialog/Netplay/CreateNetplaySessionDialog.cpp
UserInterface/Dialog/Netplay/CreateNetplaySessionDialog.ui
UserInterface/Dialog/Netplay/NetplaySessionBrowserDialog.cpp
UserInterface/Dialog/Netplay/NetplaySessionBrowserDialog.ui
UserInterface/Dialog/Netplay/NetplaySessionDialog.cpp
UserInterface/Dialog/Netplay/NetplaySessionDialog.ui
UserInterface/Dialog/Netplay/NetplaySessionPasswordDialog.cpp
UserInterface/Dialog/Netplay/NetplaySessionPasswordDialog.ui
)
endif(NETPLAY)

set_source_files_properties(${IMGUI_SOURCES} PROPERTIES GENERATED TRUE)
list(APPEND RMG_SOURCES ${IMGUI_SOURCES})

Expand Down Expand Up @@ -120,3 +139,7 @@ if (UPDATER)
target_link_libraries(RMG Qt6::Network)
endif(UPDATER)

if (NETPLAY)
target_link_libraries(RMG Qt6::WebSockets)
endif(NETPLAY)

Loading

0 comments on commit 62bfe92

Please sign in to comment.