dcnet: Power Smash support
This commit is contained in:
parent
75defb590b
commit
5df5c70994
|
@ -578,6 +578,15 @@ void CheatManager::reset(const std::string& gameId)
|
|||
cheats.emplace_back(Cheat::Type::setValue, "modem automode4 set", true, 32, addr + 0x10, 0x30202020, true); // " 0"
|
||||
}
|
||||
}
|
||||
else if (gameId == "HDR-0113") // Power Smash
|
||||
{
|
||||
cheats.emplace_back(Cheat::Type::runNextIfEq, "no dupe SYN ifeq", true, 16, 0x14d258, 0xbbce, true); // bsr SendNormalSYN
|
||||
cheats.emplace_back(Cheat::Type::setValue, "no dupe SYN set", true, 16, 0x14d258, 0x0009, true); // nop
|
||||
cheats.emplace_back(Cheat::Type::runNextIfEq, "no dupe SYN2 ifeq", true, 16, 0x14d274, 0xbb72, true); // bsr SendFakeSYN
|
||||
cheats.emplace_back(Cheat::Type::setValue, "no dupe SYN2 set", true, 16, 0x14d274, 0x0009, true); // nop
|
||||
cheats.emplace_back(Cheat::Type::runNextIfEq, "no dupe ACK ifeq", true, 16, 0x14af42, 0x430b, true); // jsr TCPInternalSendPacket
|
||||
cheats.emplace_back(Cheat::Type::setValue, "no dupe ACK set", true, 16, 0x14af42, 0x0009, true); // nop
|
||||
}
|
||||
|
||||
if (cheats.size() > cheatCount)
|
||||
setActive(true);
|
||||
|
|
|
@ -55,11 +55,10 @@ public:
|
|||
void receiveEthFrame(const u8 *frame, u32 size) override;
|
||||
};
|
||||
|
||||
template<typename SocketT>
|
||||
class PPPSocket
|
||||
{
|
||||
public:
|
||||
PPPSocket(asio::io_context& io_context, const typename SocketT::endpoint_type& endpoint,
|
||||
PPPSocket(asio::io_context& io_context, const asio::ip::tcp::endpoint& endpoint,
|
||||
const std::string& endpointName = "")
|
||||
: socket(io_context)
|
||||
{
|
||||
|
@ -71,7 +70,7 @@ public:
|
|||
receive();
|
||||
}
|
||||
|
||||
~PPPSocket() {
|
||||
virtual ~PPPSocket() {
|
||||
if (dumpfp != nullptr)
|
||||
fclose(dumpfp);
|
||||
}
|
||||
|
@ -86,8 +85,8 @@ public:
|
|||
doSend();
|
||||
}
|
||||
|
||||
private:
|
||||
void receive()
|
||||
protected:
|
||||
virtual void receive()
|
||||
{
|
||||
socket.async_read_some(asio::buffer(recvBuffer),
|
||||
[this](const std::error_code& ec, size_t len)
|
||||
|
@ -172,7 +171,7 @@ private:
|
|||
#endif
|
||||
}
|
||||
|
||||
SocketT socket;
|
||||
asio::ip::tcp::socket socket;
|
||||
std::array<u8, 1542> recvBuffer;
|
||||
std::array<u8, 1542> sendBuffer;
|
||||
u32 sendBufSize = 0;
|
||||
|
@ -182,7 +181,55 @@ private:
|
|||
u64 dump_last_time_ms;
|
||||
};
|
||||
|
||||
using PPPTcpSocket = PPPSocket<asio::ip::tcp::socket>;
|
||||
class PowerSmashPPPSocket : public PPPSocket
|
||||
{
|
||||
public:
|
||||
PowerSmashPPPSocket(asio::io_context& io_context, const asio::ip::tcp::endpoint& endpoint,
|
||||
const std::string& endpointName = "")
|
||||
: PPPSocket(io_context, endpoint, endpointName) {}
|
||||
|
||||
private:
|
||||
void receive() override
|
||||
{
|
||||
socket.async_read_some(asio::buffer(&recvBuffer[recvBufSize], recvBuffer.size() - recvBufSize),
|
||||
[this](const std::error_code& ec, size_t len)
|
||||
{
|
||||
if (ec || len == 0)
|
||||
{
|
||||
if (ec)
|
||||
ERROR_LOG(NETWORK, "Receive error: %s", ec.message().c_str());
|
||||
close();
|
||||
return;
|
||||
}
|
||||
recvBufSize += len;
|
||||
while (recvBufSize != 0)
|
||||
{
|
||||
u32 frameSize = 0;
|
||||
for (u32 i = 1; i < recvBufSize; i++)
|
||||
{
|
||||
if (recvBuffer[i] == '~') {
|
||||
frameSize = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (frameSize == 0)
|
||||
break;
|
||||
pppdump(recvBuffer.data(), frameSize, false);
|
||||
// Power Smash requires both start and end Flag Sequences
|
||||
if (recvBuffer[0] != '~')
|
||||
toModem.push('~');
|
||||
for (size_t i = 0; i < frameSize; i++)
|
||||
toModem.push(recvBuffer[i]);
|
||||
recvBufSize -= frameSize;
|
||||
if (recvBufSize != 0)
|
||||
memmove(&recvBuffer[0], &recvBuffer[frameSize], recvBufSize);
|
||||
}
|
||||
receive();
|
||||
});
|
||||
}
|
||||
|
||||
u32 recvBufSize = 0;
|
||||
};
|
||||
|
||||
class EthSocket
|
||||
{
|
||||
|
@ -609,11 +656,12 @@ private:
|
|||
|
||||
std::thread thread;
|
||||
std::unique_ptr<asio::io_context> io_context;
|
||||
std::unique_ptr<PPPTcpSocket> pppSocket;
|
||||
std::unique_ptr<PPPSocket> pppSocket;
|
||||
std::unique_ptr<EthSocket> ethSocket;
|
||||
|
||||
static constexpr uint16_t PPP_PORT = 7654;
|
||||
static constexpr uint16_t TAP_PORT = 7655;
|
||||
static constexpr uint16_t POWER_SMASH_PPP_PORT = 7656;
|
||||
friend DCNetService;
|
||||
};
|
||||
static DCNetThread thread;
|
||||
|
@ -679,6 +727,7 @@ void DCNetService::receiveEthFrame(u8 const *frame, unsigned int len)
|
|||
|
||||
void DCNetThread::connect(const asio::ip::address& address, const std::string& apname)
|
||||
{
|
||||
const bool powerSmash = settings.content.gameId == "HDR-0113";
|
||||
asio::ip::tcp::endpoint endpoint;
|
||||
if (address.is_unspecified())
|
||||
{
|
||||
|
@ -689,6 +738,8 @@ void DCNetThread::connect(const asio::ip::address& address, const std::string& a
|
|||
std::string port;
|
||||
if (config::EmulateBBA)
|
||||
port = std::to_string(TAP_PORT);
|
||||
else if (powerSmash)
|
||||
port = std::to_string(POWER_SMASH_PPP_PORT);
|
||||
else
|
||||
port = std::to_string(PPP_PORT);
|
||||
asio::ip::tcp::resolver resolver(*io_context);
|
||||
|
@ -700,14 +751,22 @@ void DCNetThread::connect(const asio::ip::address& address, const std::string& a
|
|||
throw FlycastException("Host not found");
|
||||
endpoint = *it.begin();
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
endpoint.address(address);
|
||||
endpoint.port(config::EmulateBBA ? TAP_PORT : PPP_PORT);
|
||||
if (config::EmulateBBA)
|
||||
endpoint.port(TAP_PORT);
|
||||
else if (powerSmash)
|
||||
endpoint.port(POWER_SMASH_PPP_PORT);
|
||||
else
|
||||
endpoint.port(PPP_PORT);
|
||||
}
|
||||
if (config::EmulateBBA)
|
||||
ethSocket = std::make_unique<EthSocket>(*io_context, endpoint, apname);
|
||||
else if (powerSmash)
|
||||
pppSocket = std::make_unique<PowerSmashPPPSocket>(*io_context, endpoint, apname);
|
||||
else
|
||||
pppSocket = std::make_unique<PPPTcpSocket>(*io_context, endpoint, apname);
|
||||
pppSocket = std::make_unique<PPPSocket>(*io_context, endpoint, apname);
|
||||
}
|
||||
|
||||
void DCNetThread::run()
|
||||
|
|
Loading…
Reference in New Issue