Implement GC modem adapter

This implements the GameCube modem adapter. This implementation is stable but not perfect; it drops frames if the receive FIFO length is exceeded. This is probably due to the unimplemented interrupt mentioned in the comments. If the tapserver end of the connection is aware of this limitation, it's easily circumvented by lowering the MTU of the link, but ideally this wouldn't be necessary.

This has been tested with a couple of different versions of Phantasy Star Online, including Episodes 1 & 2 Trial Edition. The Trial Edition is the only version of the game that supports the Modem Adapter and not the Broadband Adapter, which is what made this commit necessary in the first place.
This commit is contained in:
Martin Michelsen
2023-12-02 23:37:28 -08:00
parent 083116a89c
commit 02deaa6748
14 changed files with 954 additions and 7 deletions

View File

@ -49,7 +49,12 @@ void BroadbandAdapterSettingsDialog::InitControls()
break;
case Type::TapServer:
current_address = QString::fromStdString(Config::Get(Config::MAIN_BBA_TAPSERVER_DESTINATION));
case Type::ModemTapServer:
{
bool is_modem = (m_bba_type == Type::ModemTapServer);
current_address =
QString::fromStdString(Config::Get(is_modem ? Config::MAIN_MODEM_TAPSERVER_DESTINATION :
Config::MAIN_BBA_TAPSERVER_DESTINATION));
#ifdef _WIN32
address_label = new QLabel(tr("Destination (address:port):"));
address_placeholder = QStringLiteral("");
@ -58,12 +63,24 @@ void BroadbandAdapterSettingsDialog::InitControls()
#else
address_label = new QLabel(tr("Destination (UNIX socket path or address:port):"));
address_placeholder = QStringLiteral("/tmp/dolphin-tap");
description = new QLabel(tr(
"The default value \"/tmp/dolphin-tap\" will work with a local tapserver and newserv. You "
"can also enter a network location (address:port) to connect to a remote tapserver."));
if (is_modem)
{
description = new QLabel(
tr("The default value \"/tmp/dolphin-modem-tap\" will work with a local tapserver and "
"newserv. You "
"can also enter a network location (address:port) to connect to a remote tapserver."));
}
else
{
description = new QLabel(
tr("The default value \"/tmp/dolphin-tap\" will work with a local tapserver and newserv. "
"You "
"can also enter a network location (address:port) to connect to a remote tapserver."));
}
#endif
window_title = tr("BBA destination address");
break;
}
case Type::BuiltIn:
address_label = new QLabel(tr("Enter the DNS server to use:"));
@ -134,6 +151,9 @@ void BroadbandAdapterSettingsDialog::SaveAddress()
case Type::TapServer:
Config::SetBaseOrCurrent(Config::MAIN_BBA_TAPSERVER_DESTINATION, bba_new_address);
break;
case Type::ModemTapServer:
Config::SetBaseOrCurrent(Config::MAIN_MODEM_TAPSERVER_DESTINATION, bba_new_address);
break;
case Type::BuiltIn:
Config::SetBaseOrCurrent(Config::MAIN_BBA_BUILTIN_DNS, bba_new_address);
break;