Merge pull request #2974 from HeatXD/netplay_dev
Upstream Netplay Changes
This commit is contained in:
commit
5de071900d
24
README.md
24
README.md
|
@ -104,13 +104,9 @@ You will need a device with armv7 (32-bit ARM), AArch64 (64-bit ARM), or x86_64
|
|||
|
||||
Google Play is the preferred distribution mechanism and will result in smaller download sizes: https://play.google.com/store/apps/details?id=com.github.stenzek.duckstation
|
||||
|
||||
**No support is provided for the Android app**, it is free and your expectations should be in line with that. Please **do not** email me about issues about it, they will be ignored. This repository should also not be used to raise issues about the app, as it does not contain the app code, only the desktop versions.
|
||||
**No support is provided for the Android app**, it is free and your expectations should be in line with that. Please **do not** email me about issues about it, they will be ignored.
|
||||
|
||||
If you must use an APK, download links are:
|
||||
|
||||
Download link: https://www.duckstation.org/android/duckstation-android.apk
|
||||
|
||||
Changelog link: https://www.duckstation.org/android/changelog.txt
|
||||
If you must use an APK, download links are listed in https://www.duckstation.org/android/
|
||||
|
||||
To use:
|
||||
1. Install and run the app for the first time.
|
||||
|
@ -215,22 +211,6 @@ Hotkeys:
|
|||
- **Tab:** Temporarily disable speed limiter
|
||||
- **Space:** Pause/resume emulation
|
||||
|
||||
## Screenshots
|
||||
<p align="center">
|
||||
<a href="https://raw.githubusercontent.com/stenzek/duckstation/md-images/monkey.jpg"><img src="https://raw.githubusercontent.com/stenzek/duckstation/md-images/monkey.jpg" alt="Monkey Hero" width="400" /></a>
|
||||
<a href="https://raw.githubusercontent.com/stenzek/duckstation/md-images/rrt4.jpg"><img src="https://raw.githubusercontent.com/stenzek/duckstation/md-images/rrt4.jpg" alt="Ridge Racer Type 4" width="400" /></a>
|
||||
<a href="https://raw.githubusercontent.com/stenzek/duckstation/md-images/tr2.jpg"><img src="https://raw.githubusercontent.com/stenzek/duckstation/md-images/tr2.jpg" alt="Tomb Raider 2" width="400" /></a>
|
||||
<a href="https://raw.githubusercontent.com/stenzek/duckstation/md-images/quake2.jpg"><img src="https://raw.githubusercontent.com/stenzek/duckstation/md-images/quake2.jpg" alt="Quake 2" width="400" /></a>
|
||||
<a href="https://raw.githubusercontent.com/stenzek/duckstation/md-images/croc.jpg"><img src="https://raw.githubusercontent.com/stenzek/duckstation/md-images/croc.jpg" alt="Croc" width="400" /></a>
|
||||
<a href="https://raw.githubusercontent.com/stenzek/duckstation/md-images/croc2.jpg"><img src="https://raw.githubusercontent.com/stenzek/duckstation/md-images/croc2.jpg" alt="Croc 2" width="400" /></a>
|
||||
<a href="https://raw.githubusercontent.com/stenzek/duckstation/md-images/ff7.jpg"><img src="https://raw.githubusercontent.com/stenzek/duckstation/md-images/ff7.jpg" alt="Final Fantasy 7" width="400" /></a>
|
||||
<a href="https://raw.githubusercontent.com/stenzek/duckstation/md-images/mm8.jpg"><img src="https://raw.githubusercontent.com/stenzek/duckstation/md-images/mm8.jpg" alt="Mega Man 8" width="400" /></a>
|
||||
<a href="https://raw.githubusercontent.com/stenzek/duckstation/md-images/ff8.jpg"><img src="https://raw.githubusercontent.com/stenzek/duckstation/md-images/ff8.jpg" alt="Final Fantasy 8 in Fullscreen UI" width="400" /></a>
|
||||
<a href="https://raw.githubusercontent.com/stenzek/duckstation/md-images/spyro.jpg"><img src="https://raw.githubusercontent.com/stenzek/duckstation/md-images/spyro.jpg" alt="Spyro in Fullscreen UI" width="400" /></a>
|
||||
<a href="https://raw.githubusercontent.com/stenzek/duckstation/md-images/tof.jpg"><img src="https://raw.githubusercontent.com/stenzek/duckstation/md-images/tof.jpg" alt="Threads of Fate in Fullscreen UI" width="400" /></a>
|
||||
<a href="https://raw.githubusercontent.com/stenzek/duckstation/md-images/gamegrid.png"><img src="https://raw.githubusercontent.com/stenzek/duckstation/md-images/gamegrid.png" alt="Game Grid" width="400" /></a>
|
||||
</p>
|
||||
|
||||
## Disclaimers
|
||||
|
||||
Icon by icons8: https://icons8.com/icon/74847/platforms.undefined.short-title
|
||||
|
|
|
@ -53,7 +53,7 @@ void AnalogController::Reset()
|
|||
|
||||
if (m_force_analog_on_reset)
|
||||
{
|
||||
if (g_settings.controller_disable_analog_mode_forcing || System::IsRunningBIOS())
|
||||
if (g_settings.controller_disable_analog_mode_forcing || System::IsRunningUnknownGame())
|
||||
{
|
||||
Host::AddIconOSDMessage(
|
||||
fmt::format("Controller{}AnalogMode", m_index), ICON_FA_GAMEPAD,
|
||||
|
@ -835,8 +835,7 @@ static const char* s_invert_settings[] = {TRANSLATABLE("AnalogController", "Not
|
|||
|
||||
static const SettingInfo s_settings[] = {
|
||||
{SettingInfo::Type::Boolean, "ForceAnalogOnReset", TRANSLATABLE("AnalogController", "Force Analog Mode on Reset"),
|
||||
TRANSLATABLE("AnalogController", "Forces the controller to analog mode when the console is reset/powered on. May "
|
||||
"cause issues with games, so it is recommended to leave this option off."),
|
||||
TRANSLATABLE("AnalogController", "Forces the controller to analog mode when the console is reset/powered on."),
|
||||
"true"},
|
||||
{SettingInfo::Type::Boolean, "AnalogDPadInDigitalMode",
|
||||
TRANSLATABLE("AnalogController", "Use Analog Sticks for D-Pad in Digital Mode"),
|
||||
|
|
|
@ -46,6 +46,7 @@ enum class ControlMessage : u32
|
|||
ConnectResponse,
|
||||
SynchronizeSession,
|
||||
SynchronizeComplete,
|
||||
ChatMessage,
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
@ -94,6 +95,15 @@ struct ControlSynchronizeCompleteMessage
|
|||
|
||||
static ControlMessage MessageType() { return ControlMessage::SynchronizeComplete; }
|
||||
};
|
||||
|
||||
struct ControlChatMessage
|
||||
{
|
||||
ControlMessageHeader header;
|
||||
|
||||
u32 chat_message_size;
|
||||
|
||||
static ControlMessage MessageType() { return ControlMessage::ChatMessage; }
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
using SaveStateBuffer = std::unique_ptr<System::MemorySaveState>;
|
||||
|
@ -141,6 +151,7 @@ static void HandleControlMessage(s32 player_id, const ENetPacket* pkt);
|
|||
static void HandleConnectResponseMessage(s32 player_id, const ENetPacket* pkt);
|
||||
static void HandleSynchronizeSessionMessage(s32 player_id, const ENetPacket* pkt);
|
||||
static void HandleSynchronizeCompleteMessage(s32 player_id, const ENetPacket* pkt);
|
||||
static void HandleControlChatMessage(s32 player_id, const ENetPacket* pkt);
|
||||
|
||||
// l = local, r = remote
|
||||
static bool CreateGGPOSession();
|
||||
|
@ -170,7 +181,6 @@ static void Throttle();
|
|||
|
||||
// Desync Detection
|
||||
static void GenerateChecksumForFrame(int* checksum, int frame, unsigned char* buffer, int buffer_size);
|
||||
static void GenerateDesyncReport(s32 desync_frame);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Variables
|
||||
|
@ -252,7 +262,6 @@ static bool SendControlPacket(s32 player_id, const PacketWrapper<T>& pkt)
|
|||
DebugAssert(player_id >= 0 && player_id < MAX_PLAYERS && s_peers[player_id].peer);
|
||||
return SendControlPacket<T>(s_peers[player_id].peer, pkt);
|
||||
}
|
||||
|
||||
} // namespace Netplay
|
||||
|
||||
// Netplay Impl
|
||||
|
@ -505,6 +514,10 @@ void Netplay::PollEnet(Common::Timer::Value until_time)
|
|||
const u32 enet_timeout = (current_time >= until_time) ?
|
||||
0 :
|
||||
static_cast<u32>(Common::Timer::ConvertValueToMilliseconds(until_time - current_time));
|
||||
|
||||
// make sure s_enet_host exists
|
||||
Assert(s_enet_host);
|
||||
|
||||
const int res = enet_host_service(s_enet_host, &event, enet_timeout);
|
||||
if (res > 0)
|
||||
{
|
||||
|
@ -514,7 +527,6 @@ void Netplay::PollEnet(Common::Timer::Value until_time)
|
|||
current_time = Common::Timer::GetCurrentValue();
|
||||
continue;
|
||||
}
|
||||
|
||||
// exit once we're nonblocking
|
||||
current_time = Common::Timer::GetCurrentValue();
|
||||
if (enet_timeout == 0 || current_time >= until_time)
|
||||
|
@ -693,6 +705,10 @@ void Netplay::HandleControlMessage(s32 player_id, const ENetPacket* pkt)
|
|||
HandleSynchronizeCompleteMessage(player_id, pkt);
|
||||
break;
|
||||
|
||||
case ControlMessage::ChatMessage:
|
||||
HandleControlChatMessage(player_id, pkt);
|
||||
break;
|
||||
|
||||
default:
|
||||
Log_ErrorPrintf("Unhandled control packet %u from player %d of size %zu", hdr->type, player_id, pkt->dataLength);
|
||||
break;
|
||||
|
@ -1003,6 +1019,22 @@ void Netplay::HandleSynchronizeCompleteMessage(s32 player_id, const ENetPacket*
|
|||
CheckForCompleteResynchronize();
|
||||
}
|
||||
|
||||
void Netplay::HandleControlChatMessage(s32 player_id, const ENetPacket* pkt)
|
||||
{
|
||||
const ControlChatMessage* msg = reinterpret_cast<const ControlChatMessage*>(pkt->data);
|
||||
if (pkt->dataLength < sizeof(ControlChatMessage) ||
|
||||
pkt->dataLength < (sizeof(ControlChatMessage) + msg->chat_message_size))
|
||||
{
|
||||
// invalid chat message. ignore.
|
||||
return;
|
||||
}
|
||||
|
||||
std::string message(pkt->data + sizeof(ControlChatMessage),
|
||||
pkt->data + sizeof(ControlChatMessage) + msg->chat_message_size);
|
||||
|
||||
Host::OnNetplayMessage(fmt::format("Player {}: {}", PlayerIdToGGPOHandle(player_id), message));
|
||||
}
|
||||
|
||||
void Netplay::CheckForCompleteResynchronize()
|
||||
{
|
||||
if (s_synchronized_players == s_num_players)
|
||||
|
@ -1065,6 +1097,9 @@ void Netplay::UpdateThrottlePeriod()
|
|||
|
||||
void Netplay::HandleTimeSyncEvent(float frame_delta, int update_interval)
|
||||
{
|
||||
// only activate timesync if its worth correcting.
|
||||
if (std::abs(frame_delta) < 1.0f)
|
||||
return;
|
||||
// Distribute the frame difference over the next N * 0.75 frames.
|
||||
// only part of the interval time is used since we want to come back to normal speed.
|
||||
// otherwise we will keep spiraling into unplayable gameplay.
|
||||
|
@ -1140,37 +1175,6 @@ void Netplay::GenerateChecksumForFrame(int* checksum, int frame, unsigned char*
|
|||
// Log_VerbosePrintf("Netplay Checksum: f:%d wf:%d c:%u", frame, frame % num_group_of_pages, *checksum);
|
||||
}
|
||||
|
||||
void Netplay::GenerateDesyncReport(s32 desync_frame)
|
||||
{
|
||||
std::string path = "\\netplaylogs\\desync_frame_" + std::to_string(desync_frame) + "_p" +
|
||||
std::to_string(s_local_handle) + "_" + System::GetRunningSerial() + "_.txt";
|
||||
std::string filename = EmuFolders::Dumps + path;
|
||||
|
||||
std::unique_ptr<ByteStream> stream =
|
||||
ByteStream::OpenFile(filename.c_str(), BYTESTREAM_OPEN_CREATE | BYTESTREAM_OPEN_WRITE | BYTESTREAM_OPEN_TRUNCATE |
|
||||
BYTESTREAM_OPEN_ATOMIC_UPDATE | BYTESTREAM_OPEN_STREAMED);
|
||||
if (!stream)
|
||||
{
|
||||
Log_VerbosePrint("desync log creation failed to create stream");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ByteStream::WriteBinaryToStream(stream.get(),
|
||||
s_save_buffer_pool.back().get()->state_stream.get()->GetMemoryPointer(),
|
||||
s_save_buffer_pool.back().get()->state_stream.get()->GetMemorySize()))
|
||||
{
|
||||
Log_VerbosePrint("desync log creation failed to write the stream");
|
||||
stream->Discard();
|
||||
return;
|
||||
}
|
||||
/* stream->Write(s_save_buffer_pool.back().get()->state_stream.get()->GetMemoryPointer(),
|
||||
s_save_buffer_pool.back().get()->state_stream.get()->GetMemorySize());*/
|
||||
|
||||
stream->Commit();
|
||||
|
||||
Log_VerbosePrintf("desync log created for frame %d", desync_frame);
|
||||
}
|
||||
|
||||
void Netplay::AdvanceFrame()
|
||||
{
|
||||
ggpo_advance_frame(s_ggpo, 0);
|
||||
|
@ -1178,19 +1182,13 @@ void Netplay::AdvanceFrame()
|
|||
|
||||
void Netplay::RunFrame()
|
||||
{
|
||||
PollEnet(0);
|
||||
|
||||
if (!s_ggpo)
|
||||
return;
|
||||
// housekeeping
|
||||
// TODO: get rid of double polling
|
||||
PollEnet(0);
|
||||
if (!s_ggpo)
|
||||
return;
|
||||
|
||||
ggpo_network_idle(s_ggpo);
|
||||
PollEnet(0);
|
||||
if (!s_ggpo)
|
||||
return;
|
||||
|
||||
ggpo_idle(s_ggpo);
|
||||
|
||||
// run game
|
||||
auto result = GGPO_OK;
|
||||
int disconnect_flags = 0;
|
||||
|
@ -1238,7 +1236,36 @@ Netplay::Input Netplay::ReadLocalInput()
|
|||
return inp;
|
||||
}
|
||||
|
||||
void Netplay::SendMsg(const char* msg) {}
|
||||
void Netplay::SendMsg(std::string msg)
|
||||
{
|
||||
ControlChatMessage header{};
|
||||
const size_t msg_size = msg.size();
|
||||
|
||||
header.header.type = ControlMessage::ChatMessage;
|
||||
header.header.size = sizeof(ControlChatMessage) + msg_size;
|
||||
header.chat_message_size = msg_size;
|
||||
|
||||
ENetPacket* pkt = enet_packet_create(nullptr, sizeof(header) + msg_size, ENET_PACKET_FLAG_RELIABLE);
|
||||
std::memcpy(pkt->data, &header, sizeof(header));
|
||||
std::memcpy(pkt->data + sizeof(header), msg.c_str(), msg_size);
|
||||
|
||||
for (s32 i = 0; i < MAX_PLAYERS; i++)
|
||||
{
|
||||
if (!s_peers[i].peer)
|
||||
continue;
|
||||
|
||||
const int err = enet_peer_send(s_peers[i].peer, ENET_CHANNEL_CONTROL, pkt);
|
||||
if (err != 0)
|
||||
{
|
||||
// failed to send netplay message? just clean it up.
|
||||
Log_ErrorPrint("Failed to send netplay message");
|
||||
enet_packet_destroy(pkt);
|
||||
}
|
||||
}
|
||||
|
||||
// add own netplay message locally to netplay messages
|
||||
Host::OnNetplayMessage(fmt::format("Player {}: {}", s_local_handle, msg));
|
||||
}
|
||||
|
||||
GGPOErrorCode Netplay::SyncInput(Netplay::Input inputs[2], int* disconnect_flags)
|
||||
{
|
||||
|
@ -1288,9 +1315,10 @@ void Netplay::StartNetplaySession(s32 local_handle, u16 local_port, std::string&
|
|||
Log_ErrorPrint("Failed to Create Netplay Session!");
|
||||
System::ShutdownSystem(false);
|
||||
}
|
||||
else
|
||||
else if (IsHost())
|
||||
{
|
||||
// Load savestate if available
|
||||
// Load savestate if available and only when you are the host.
|
||||
// the other peers will get state from the host
|
||||
std::string save = EmuFolders::SaveStates + "/netplay/" + System::GetRunningSerial() + ".sav";
|
||||
System::LoadState(save.c_str());
|
||||
}
|
||||
|
@ -1377,8 +1405,7 @@ bool Netplay::NpAdvFrameCb(void* ctx, int flags)
|
|||
bool Netplay::NpSaveFrameCb(void* ctx, unsigned char** buffer, int* len, int* checksum, int frame)
|
||||
{
|
||||
SaveStateBuffer our_buffer;
|
||||
// min size is 2 because otherwise the desync logger doesnt have enough time to dump the state.
|
||||
if (s_save_buffer_pool.size() < 2)
|
||||
if (s_save_buffer_pool.empty())
|
||||
{
|
||||
our_buffer = std::make_unique<System::MemorySaveState>();
|
||||
}
|
||||
|
@ -1465,7 +1492,6 @@ bool Netplay::NpOnEventCb(void* ctx, GGPOEvent* ev)
|
|||
CurrentFrame(), ev->u.desync.nFrameOfDesync,
|
||||
CurrentFrame() - ev->u.desync.nFrameOfDesync, ev->u.desync.ourCheckSum,
|
||||
ev->u.desync.remoteChecksum));
|
||||
GenerateDesyncReport(ev->u.desync.nFrameOfDesync);
|
||||
break;
|
||||
default:
|
||||
Host::OnNetplayMessage(fmt::format("Netplay Event Code: {}", static_cast<int>(ev->code)));
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace Netplay {
|
|||
enum : s32
|
||||
{
|
||||
// Maximum number of emulated controllers.
|
||||
MAX_PLAYERS = 2,
|
||||
MAX_PLAYERS = 2,
|
||||
// Maximum netplay prediction frames
|
||||
MAX_ROLLBACK_FRAMES = 8,
|
||||
};
|
||||
|
@ -36,7 +36,7 @@ void ExecuteNetplay();
|
|||
|
||||
void CollectInput(u32 slot, u32 bind, float value);
|
||||
|
||||
void SendMsg(const char* msg);
|
||||
void SendMsg(std::string msg);
|
||||
|
||||
s32 GetPing();
|
||||
u32 GetMaxPrediction();
|
||||
|
|
|
@ -138,7 +138,7 @@ static BIOS::Hash s_bios_hash = {};
|
|||
static std::string s_running_game_path;
|
||||
static std::string s_running_game_serial;
|
||||
static std::string s_running_game_title;
|
||||
static bool s_running_bios;
|
||||
static bool s_running_unknown_game;
|
||||
|
||||
static float s_throttle_frequency = 60.0f;
|
||||
static float s_target_speed = 1.0f;
|
||||
|
@ -320,9 +320,9 @@ const std::string& System::GetRunningTitle()
|
|||
return s_running_game_title;
|
||||
}
|
||||
|
||||
bool System::IsRunningBIOS()
|
||||
bool System::IsRunningUnknownGame()
|
||||
{
|
||||
return s_running_bios;
|
||||
return s_running_unknown_game;
|
||||
}
|
||||
|
||||
const BIOS::ImageInfo* System::GetBIOSImageInfo()
|
||||
|
@ -958,9 +958,6 @@ void System::ResetSystem()
|
|||
ResetPerformanceCounters();
|
||||
ResetThrottler();
|
||||
Host::AddOSDMessage(Host::TranslateStdString("OSDMessage", "System reset."));
|
||||
|
||||
// need to clear this here, because of eject disc -> reset.
|
||||
s_running_bios = !s_running_game_path.empty();
|
||||
}
|
||||
|
||||
void System::PauseSystem(bool paused)
|
||||
|
@ -1239,9 +1236,6 @@ bool System::BootSystem(SystemBootParameters parameters)
|
|||
return false;
|
||||
}
|
||||
|
||||
// Allow controller analog mode for EXEs and PSFs.
|
||||
s_running_bios = s_running_game_path.empty() && exe_boot.empty() && psf_boot.empty();
|
||||
|
||||
UpdateControllers();
|
||||
UpdateMemoryCardTypes();
|
||||
UpdateMultitaps();
|
||||
|
@ -1510,7 +1504,7 @@ void System::ClearRunningGame()
|
|||
s_running_game_serial.clear();
|
||||
s_running_game_path.clear();
|
||||
s_running_game_title.clear();
|
||||
s_running_bios = false;
|
||||
s_running_unknown_game = false;
|
||||
s_cheat_list.reset();
|
||||
s_state = State::Shutdown;
|
||||
|
||||
|
@ -3053,6 +3047,7 @@ void System::UpdateRunningGame(const char* path, CDImage* image, bool booting)
|
|||
s_running_game_path.clear();
|
||||
s_running_game_serial.clear();
|
||||
s_running_game_title.clear();
|
||||
s_running_unknown_game = true;
|
||||
|
||||
if (path && std::strlen(path) > 0)
|
||||
{
|
||||
|
@ -3070,6 +3065,7 @@ void System::UpdateRunningGame(const char* path, CDImage* image, bool booting)
|
|||
{
|
||||
s_running_game_serial = entry->serial;
|
||||
s_running_game_title = entry->title;
|
||||
s_running_unknown_game = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -184,7 +184,7 @@ const std::string& GetRunningPath();
|
|||
const std::string& GetRunningSerial();
|
||||
const std::string& GetRunningTitle();
|
||||
|
||||
bool IsRunningBIOS();
|
||||
bool IsRunningUnknownGame();
|
||||
const BIOS::ImageInfo* GetBIOSImageInfo();
|
||||
const BIOS::Hash& GetBIOSHash();
|
||||
|
||||
|
|
|
@ -1568,10 +1568,6 @@ void MainWindow::setupAdditionalUi()
|
|||
m_status_vps_widget->setFixedSize(120, 16);
|
||||
m_status_vps_widget->hide();
|
||||
|
||||
m_status_ping_widget = new QLabel(m_ui.statusBar);
|
||||
m_status_ping_widget->setFixedSize(110, 16);
|
||||
m_status_ping_widget->hide();
|
||||
|
||||
m_settings_toolbar_menu = new QMenu(m_ui.toolBar);
|
||||
m_settings_toolbar_menu->addAction(m_ui.actionSettings);
|
||||
m_settings_toolbar_menu->addAction(m_ui.actionViewGameProperties);
|
||||
|
@ -1777,7 +1773,6 @@ void MainWindow::updateStatusBarWidgetVisibility()
|
|||
Update(m_status_resolution_widget, s_system_valid && !s_system_paused, 0);
|
||||
Update(m_status_fps_widget, s_system_valid && !s_system_paused, 0);
|
||||
Update(m_status_vps_widget, s_system_valid && !s_system_paused, 0);
|
||||
Update(m_status_ping_widget, s_system_valid && !s_system_paused && m_netplay_window != nullptr, 0);
|
||||
}
|
||||
|
||||
void MainWindow::updateWindowTitle()
|
||||
|
|
|
@ -90,7 +90,6 @@ public:
|
|||
ALWAYS_INLINE QLabel* getStatusResolutionWidget() const { return m_status_resolution_widget; }
|
||||
ALWAYS_INLINE QLabel* getStatusFPSWidget() const { return m_status_fps_widget; }
|
||||
ALWAYS_INLINE QLabel* getStatusVPSWidget() const { return m_status_vps_widget; }
|
||||
ALWAYS_INLINE QLabel* getStatusPingWidget() const { return m_status_ping_widget; }
|
||||
|
||||
public Q_SLOTS:
|
||||
/// Updates debug menu visibility (hides if disabled).
|
||||
|
@ -266,7 +265,6 @@ private:
|
|||
QLabel* m_status_renderer_widget = nullptr;
|
||||
QLabel* m_status_fps_widget = nullptr;
|
||||
QLabel* m_status_vps_widget = nullptr;
|
||||
QLabel* m_status_ping_widget = nullptr;
|
||||
QLabel* m_status_resolution_widget = nullptr;
|
||||
|
||||
QMenu* m_settings_toolbar_menu = nullptr;
|
||||
|
|
|
@ -1079,12 +1079,6 @@ void EmuThread::startNetplaySession(int local_handle, quint16 local_port, const
|
|||
Q_ARG(quint16, remote_port), Q_ARG(int, input_delay), Q_ARG(const QString&, game_path));
|
||||
return;
|
||||
}
|
||||
// disable block linking and disable rewind and runahead during a netplay session
|
||||
g_settings.cpu_recompiler_block_linking = false;
|
||||
g_settings.rewind_enable = false;
|
||||
g_settings.runahead_frames = 0;
|
||||
|
||||
Log_WarningPrintf("Disabling block linking, runahead and rewind due to rollback.");
|
||||
|
||||
auto remAddr = remote_addr.trimmed().toStdString();
|
||||
auto gamePath = game_path.trimmed().toStdString();
|
||||
|
@ -1101,7 +1095,8 @@ void EmuThread::sendNetplayMessage(const QString& message)
|
|||
QMetaObject::invokeMethod(this, "sendNetplayMessage", Qt::QueuedConnection, Q_ARG(const QString&, message));
|
||||
return;
|
||||
}
|
||||
Netplay::SendMsg(message.toStdString().c_str());
|
||||
// TODO REDO NETPLAY UI
|
||||
// Netplay::SendMsg(message.toStdString().c_str());
|
||||
}
|
||||
|
||||
void EmuThread::stopNetplaySession()
|
||||
|
@ -1714,14 +1709,6 @@ void EmuThread::updatePerformanceCounters()
|
|||
m_last_speed = speed;
|
||||
m_last_video_fps = vfps;
|
||||
}
|
||||
|
||||
const s32 ping = Netplay::GetPing();
|
||||
if (m_last_ping != ping)
|
||||
{
|
||||
QMetaObject::invokeMethod(g_main_window->getStatusPingWidget(), "setText", Qt::QueuedConnection,
|
||||
Q_ARG(const QString&, tr("Netplay Ping: %1 ").arg(ping, 0, 'f', 0)));
|
||||
m_last_ping = ping;
|
||||
}
|
||||
}
|
||||
|
||||
void EmuThread::resetPerformanceCounters()
|
||||
|
|
|
@ -175,8 +175,10 @@ void ImGuiManager::DrawNetplayChatDialog()
|
|||
const bool close_chat =
|
||||
send_message || (s_netplay_chat_message.empty() && (ImGui::IsKeyPressed(ImGuiKey_Backspace)) ||
|
||||
ImGui::IsKeyPressed(ImGuiKey_Escape));
|
||||
|
||||
// sending netplay message
|
||||
if (send_message && !s_netplay_chat_message.empty())
|
||||
Netplay::SendMsg(s_netplay_chat_message.c_str());
|
||||
Netplay::SendMsg(s_netplay_chat_message);
|
||||
|
||||
const ImGuiIO& io = ImGui::GetIO();
|
||||
const ImGuiStyle& style = ImGui::GetStyle();
|
||||
|
|
Loading…
Reference in New Issue