enable rollback (#1378)

This commit is contained in:
Logan McNaughton authored and GitHub committed 2026-11-11 18:12:29 +00:00
1 parent aed1158264
commit 23345321d8
13 files changed
+43 -69

No files matched your search

+2 -2
View File
@@ -1,6 +1,6 @@
# gopher64
Gopher64 is a cross-platform N64 emulator. Some notable features:
* Netplay
* Rollback netplay
* Homebrew support
* Upscaling
* CRT shader
@@ -42,7 +42,7 @@ Keys are mapped according to [these defaults](https://github.com/gopher64/gopher
## netplay
Gopher64 supports P2P netplay (online play with others).
Gopher64 supports P2P rollback netplay (online play with others).
Please read the [guide](https://github.com/gopher64/gopher64/wiki/Netplay-Guide) before trying out netplay.
+2 -2
View File
@@ -417,11 +417,11 @@ msgstr "Nachricht senden"
#: src/ui/gui/netplay_wait.slint:104
msgctxt "NetplayWait"
msgid ""
"Setting the input delay too low will cause the game to lag.\n"
"Setting the input delay too low will cause frequent rollbacks.\n"
"You can lower the input delay in-game by pressing Alt+[ and raise it with "
"Alt+]."
msgstr ""
"Eine zu niedrige Eingabeverzögerung führt zu Ruckeln im Spiel.\n"
"Eine zu niedrige Eingabeverzögerung führt zu häufigen Rollbacks.\n"
"Sie können die Eingabeverzögerung im Spiel mit Alt+[ verringern und mit "
"Alt+] erhöhen."
+3 -3
View File
@@ -415,12 +415,12 @@ msgstr "Enviar mensaje"
#: src/ui/gui/netplay_wait.slint:104
msgctxt "NetplayWait"
msgid ""
"Setting the input delay too low will cause the game to lag.\n"
"Setting the input delay too low will cause frequent rollbacks.\n"
"You can lower the input delay in-game by pressing Alt+[ and raise it with "
"Alt+]."
msgstr ""
"Configurar un retardo de entrada demasiado bajo hará que el juego se "
"ralentice.\n"
"Configurar un retardo de entrada demasiado bajo provocará rollbacks "
"frecuentes.\n"
"Puedes reducir el retardo de entrada en el juego pulsando Alt+[ y aumentarlo "
"con Alt+]."
+2 -2
View File
@@ -417,11 +417,11 @@ msgstr "Envoyer"
#: src/ui/gui/netplay_wait.slint:104
msgctxt "NetplayWait"
msgid ""
"Setting the input delay too low will cause the game to lag.\n"
"Setting the input delay too low will cause frequent rollbacks.\n"
"You can lower the input delay in-game by pressing Alt+[ and raise it with "
"Alt+]."
msgstr ""
"Régler le délai d'entrée trop bas provoquera des ralentissements.\n"
"Régler le délai d'entrée trop bas provoquera des rollbacks fréquents.\n"
"Vous pouvez diminuer le délai d'entrée en jeu avec Alt+[ et l'augmenter avec "
"Alt+]."
+2 -2
View File
@@ -401,8 +401,8 @@ msgstr ""
#: src/ui/gui/netplay_wait.slint:104
msgctxt "NetplayWait"
msgid ""
"Setting the input delay too low will cause the game to lag.\nYou can lower "
"the input delay in-game by pressing Alt+[ and raise it with Alt+]."
"Setting the input delay too low will cause frequent rollbacks.\nYou can "
"lower the input delay in-game by pressing Alt+[ and raise it with Alt+]."
msgstr ""
#: src/ui/gui/netplay_wait.slint:112
+2 -2
View File
@@ -414,11 +414,11 @@ msgstr "送信"
#: src/ui/gui/netplay_wait.slint:104
msgctxt "NetplayWait"
msgid ""
"Setting the input delay too low will cause the game to lag.\n"
"Setting the input delay too low will cause frequent rollbacks.\n"
"You can lower the input delay in-game by pressing Alt+[ and raise it with "
"Alt+]."
msgstr ""
"入力遅延を低く設定しすぎるとゲームが遅延します。\n"
"入力遅延を低く設定しすぎると頻繁にロールバックが発生します。\n"
"Alt+[ でゲーム内の入力遅延を下げ、Alt+] で上げることができます。"
#: src/ui/gui/netplay_wait.slint:112
+2 -2
View File
@@ -416,11 +416,11 @@ msgstr "Bericht verzenden"
#: src/ui/gui/netplay_wait.slint:104
msgctxt "NetplayWait"
msgid ""
"Setting the input delay too low will cause the game to lag.\n"
"Setting the input delay too low will cause frequent rollbacks.\n"
"You can lower the input delay in-game by pressing Alt+[ and raise it with "
"Alt+]."
msgstr ""
"Een te lage invoervertraging zorgt ervoor dat het spel gaat haperen.\n"
"Een te lage invoervertraging zorgt voor frequente rollbacks.\n"
"Je kunt de invoervertraging in het spel verlagen met Alt+[ en verhogen met "
"Alt+]."
@@ -417,11 +417,11 @@ msgstr "Enviar Mensagem"
#: src/ui/gui/netplay_wait.slint:104
msgctxt "NetplayWait"
msgid ""
"Setting the input delay too low will cause the game to lag.\n"
"Setting the input delay too low will cause frequent rollbacks.\n"
"You can lower the input delay in-game by pressing Alt+[ and raise it with "
"Alt+]."
msgstr ""
"Definir o atraso de entrada muito baixo causará lag no jogo.\n"
"Definir o atraso de entrada muito baixo causará rollbacks frequentes.\n"
"Você pode diminuir o atraso de entrada no jogo pressionando Alt+[ e aumentá-"
"lo com Alt+]."
+2 -2
View File
@@ -416,11 +416,11 @@ msgstr "Отправить сообщение"
#: src/ui/gui/netplay_wait.slint:104
msgctxt "NetplayWait"
msgid ""
"Setting the input delay too low will cause the game to lag.\n"
"Setting the input delay too low will cause frequent rollbacks.\n"
"You can lower the input delay in-game by pressing Alt+[ and raise it with "
"Alt+]."
msgstr ""
"Слишком низкая задержка ввода вызовет лаги в игре.\n"
"Слишком низкая задержка ввода вызовет частые откаты.\n"
"Вы можете уменьшить задержку ввода в игре, нажав Alt+[, и увеличить её с "
"помощью Alt+]."
+4 -35
View File
@@ -107,7 +107,6 @@ fn process_reliable_messages(netplay: &mut Netplay) {
.messages
.insert(decoded_message.name, decoded_message.data);
netplay.incoming_message.clear();
check_input_delay(netplay);
check_disconnect(netplay);
}
}
@@ -203,20 +202,11 @@ pub fn receive_save(netplay: &mut Netplay, save_type: &str, save_data: &mut Vec<
*save_data = message;
}
pub fn send_input_delay(netplay: &mut Netplay, input_delay: usize) {
pub fn change_input_delay(netplay: &mut Netplay, input_delay: usize) {
if !(1..=MAX_PREDICTION_WINDOW).contains(&input_delay) {
return;
}
let message = NetplayMessage {
name: "input_delay".to_string(),
data: (input_delay as u64).to_be_bytes().to_vec(),
};
send_message(netplay, message);
change_input_delay(netplay, input_delay);
}
fn change_input_delay(netplay: &mut Netplay, input_delay: usize) {
netplay.input_delay = input_delay;
for handle in netplay.session.local_player_handles() {
if let Err(e) = netplay.session.set_input_delay(handle, input_delay) {
@@ -230,15 +220,6 @@ fn change_input_delay(netplay: &mut Netplay, input_delay: usize) {
}
}
fn check_input_delay(netplay: &mut Netplay) {
if let Some(data) = netplay.messages.remove("input_delay") {
let input_delay = u64::from_be_bytes(data.try_into().unwrap()) as usize;
if input_delay != netplay.input_delay {
change_input_delay(netplay, input_delay);
}
}
}
fn check_disconnect(netplay: &mut Netplay) {
if !netplay.disconnected && netplay.messages.remove("disconnect").is_some() {
netplay.disconnected = true;
@@ -272,7 +253,7 @@ pub fn process_requests(
if let Some(request) = device.netplay.as_mut().unwrap().requests.pop_front() {
match request {
ggrs::GgrsRequest::SaveGameState { cell, frame } => {
//savestates::create_savestate(device, true, Some(frame));
savestates::create_savestate(device, true, Some(frame));
let mut hasher = sha2::Sha256::new();
for reg in device.cpu.cop0.regs.as_ref() {
@@ -341,26 +322,13 @@ fn process_netplay(device: &mut device::Device) {
fn advance_frame(device: &mut device::Device) {
let netplay = device.netplay.as_mut().unwrap();
let local_input = if netplay.session.current_frame() > netplay.session.max_prediction() as i32 {
ui::input::get(&mut device.ui, 0)
} else {
//workaround for disabled rollback
ui::input::InputData::default()
};
let local_input = ui::input::get(&mut device.ui, 0);
let local_handle = *netplay.session.local_player_handles().first().unwrap();
netplay
.session
.add_local_input(local_handle, local_input)
.unwrap();
// avoid rollback
while !netplay.disconnected
&& netplay.session.current_frame() > netplay.session.confirmed_frame()
&& netplay.session.confirmed_frame() != ggrs::NULL_FRAME
{
poll_clients(netplay);
}
if netplay.disconnected {
netplay.requests.push_back(ggrs::GgrsRequest::AdvanceFrame {
inputs: vec![
@@ -503,6 +471,7 @@ pub fn init(
.with_num_players(netplay_config.number_of_players)
.unwrap()
.with_input_delay(netplay_config.input_delay)
.with_sparse_saving_mode(true)
.with_fps(if pal { 50 } else { 60 })
.unwrap()
.with_desync_detection_mode(ggrs::DesyncDetection::On { interval: 60 })
+2 -2
View File
@@ -101,12 +101,12 @@ export component NetplayWait inherits Page {
}
Text {
text: NetplayData.player_name == NetplayWaitData.players[0] ? @tr("Setting the input delay too low will cause the game to lag.\nYou can lower the input delay in-game by pressing Alt+[ and raise it with Alt+].") : NetplayWaitData.motd;
text: @tr("Setting the input delay too low will cause frequent rollbacks.\nYou can lower the input delay in-game by pressing Alt+[ and raise it with Alt+].");
horizontal-alignment: center;
wrap: word-wrap;
}
if NetplayData.player_name == NetplayWaitData.players[0]: HorizontalBox {
HorizontalBox {
alignment: center;
Text {
text: @tr("Local Input Delay:");
+15 -8
View File
@@ -799,14 +799,21 @@ fn setup_wait_window(
.upgrade_in_event_loop(move |handle| {
let player_name = handle.get_netplay_player_name();
let players = handle.get_netplay_players();
let input_delay = response
.sessions
.iter()
.next()
.unwrap()
.1
.input_delay
.unwrap();
// Input delay is per-player: use our own choice, falling back
// to the host's if our recommendation hasn't been calculated yet.
let local_input_delay = handle.get_netplay_input_delay();
let input_delay = if local_input_delay > 0 {
local_input_delay as usize
} else {
response
.sessions
.iter()
.next()
.unwrap()
.1
.input_delay
.unwrap()
};
let player_number =
players.iter().position(|x| x == player_name).unwrap();
run_rom(
+3 -5
View File
@@ -271,13 +271,11 @@ pub fn check_callback(device: &mut device::Device) -> (bool, bool) {
ui::audio::raise_audio_volume(&mut device.ui);
}
if let Some(netplay) = &mut device.netplay
&& netplay.player_number == 0
{
if let Some(netplay) = &mut device.netplay {
if callback.decrease_input_delay {
netplay::send_input_delay(netplay, netplay.input_delay - 1);
netplay::change_input_delay(netplay, netplay.input_delay.saturating_sub(1));
} else if callback.increase_input_delay {
netplay::send_input_delay(netplay, netplay.input_delay + 1);
netplay::change_input_delay(netplay, netplay.input_delay + 1);
}
}
(speed_limiter_toggled, callback.paused)