From a698f8cd06bb4e044ada37b6c423cdf471919fd1 Mon Sep 17 00:00:00 2001 From: Raphael Assenat Date: Thu, 4 Mar 2021 15:47:12 +0900 Subject: [PATCH] Correct accuracy of poll interval settings on 2-player adapters The pauses recently introduced for supporting the Brawler 64 wireless work fine in single-player mode (i.e. the poll interval setting in the adapter manager is honored), but in two-player mode, the pauses add up and the actual polling rate was slower than what was requested. This corrects the issue, but unfortunately, on dual port adapters, this means that a setting of 4ms or higher is needed to use a Brawler 64. --- n64.c | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/n64.c b/n64.c index 557f2df..d49b82b 100644 --- a/n64.c +++ b/n64.c @@ -22,6 +22,7 @@ #include "n64.h" #include "gcn64_protocol.h" #include "eeprom.h" +#include "main.h" // for num_players #undef BUTTON_A_RUMBLE_TEST @@ -113,15 +114,37 @@ static char n64Update(unsigned char chn) /* The brawler 64 wireless gamepad does not like when the get caps command is followed * too closely by the get status command. Without a long pause between the two commands, - * it just returns an all zeros. */ - if (g_eeprom_data.cfg.poll_interval[0] >= 4) { - _delay_ms(2.5); - } else if (g_eeprom_data.cfg.poll_interval[0] >= 3) { - _delay_ms(1.5); - } else if (g_eeprom_data.cfg.poll_interval[0] >= 2) { - _delay_ms(1.25); // does not work at 1ms + * it just returns all zeros. */ + if (num_players > 1) { + // n64Update is called two times on two-player adapters. This + // means time lost waiting here doubles. Without this, the controllers + // are no longer being polled at the rate set in the gui, which is bad. + // (I want this setting to be reliable) + // + // So on dual port adapters, brawler 64 wireless controllers will be + // usable only at intervals >= 4ms. + // + // TODO: Interleave access like this to allow a higher polling + // frequency: Read caps port 1, Read caps port 2, delay, Read status port 1, + // read status port 2. (Maybe this could make 3ms intervals work) + // + if (g_eeprom_data.cfg.poll_interval[0] >= 8) { + _delay_ms(2.5); + } else if (g_eeprom_data.cfg.poll_interval[0] >= 6) { + _delay_ms(1.5); + } else if (g_eeprom_data.cfg.poll_interval[0] >= 4) { + _delay_ms(1.25); + } + } + else { + if (g_eeprom_data.cfg.poll_interval[0] >= 4) { + _delay_ms(2.5); + } else if (g_eeprom_data.cfg.poll_interval[0] >= 3) { + _delay_ms(1.5); + } else if (g_eeprom_data.cfg.poll_interval[0] >= 2) { + _delay_ms(1.25); // does not work at 1ms + } } - /* Detect when a pack becomes present and schedule initialisation when it happens. */ if ((caps[2] & 0x01) && (n64_rumble_state[chn] == RSTATE_UNAVAILABLE)) {