alienfnt: support for serial modem and worldwide ranking server
Emulate modem on sh4 serial port. Use picotcp stack to handle ppp protocol. Include nvmem with network settings (server at alienfront.duckdns.org, disabled by default).
This commit is contained in:
parent
858174791f
commit
92a1c1891b
|
@ -924,6 +924,7 @@ target_sources(${PROJECT_NAME} PRIVATE
|
|||
|
||||
cmrc_add_resources(flycast-resources
|
||||
WHENCE resources
|
||||
resources/flash/alienfnt.nvmem.zip # network settings
|
||||
resources/flash/gunsur2.nvmem.zip
|
||||
resources/flash/otrigger.nvmem.zip
|
||||
resources/flash/wldkicks.nvmem.zip # free play
|
||||
|
@ -1013,6 +1014,8 @@ if(NOT LIBRETRO)
|
|||
endif()
|
||||
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/network/alienfnt_modem.cpp
|
||||
core/network/alienfnt_modem.h
|
||||
core/network/dns.cpp
|
||||
core/network/ggpo.cpp
|
||||
core/network/ggpo.h
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "touchscreen.h"
|
||||
#include "printer.h"
|
||||
#include "oslib/storage.h"
|
||||
#include "network/alienfnt_modem.h"
|
||||
|
||||
Cartridge *CurrentCartridge;
|
||||
bool bios_loaded = false;
|
||||
|
@ -650,6 +651,10 @@ void naomi_cart_LoadRom(const std::string& path, const std::string& fileName, Lo
|
|||
{
|
||||
card_reader::barcodeInit();
|
||||
}
|
||||
else if (gameId == "ALIEN FRONT")
|
||||
{
|
||||
serialModemInit();
|
||||
}
|
||||
if (gameId == " TOUCH DE UNOH -------------"
|
||||
|| gameId == " TOUCH DE UNOH 2 -----------"
|
||||
// only for F355 Deluxe
|
||||
|
@ -714,6 +719,7 @@ void naomi_cart_Close()
|
|||
printer::term();
|
||||
card_reader::initdTerm();
|
||||
card_reader::barcodeTerm();
|
||||
serialModemTerm();
|
||||
delete CurrentCartridge;
|
||||
CurrentCartridge = nullptr;
|
||||
NaomiGameInputs = nullptr;
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
Copyright 2023 flyinghead
|
||||
|
||||
This file is part of Flycast.
|
||||
|
||||
Flycast is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Flycast is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "alienfnt_modem.h"
|
||||
#include "hw/sh4/sh4_sched.h"
|
||||
#include "hw/sh4/modules/modules.h"
|
||||
#include "picoppp.h"
|
||||
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
|
||||
struct ModemEmu : public SerialPipe
|
||||
{
|
||||
ModemEmu() {
|
||||
serial_setPipe(this);
|
||||
schedId = sh4_sched_register(0, schedCallback);
|
||||
}
|
||||
|
||||
~ModemEmu() {
|
||||
sh4_sched_unregister(schedId);
|
||||
stop_pico();
|
||||
serial_setPipe(nullptr);
|
||||
}
|
||||
|
||||
u8 read() override
|
||||
{
|
||||
if (!toSend.empty())
|
||||
{
|
||||
char c = toSend.front();
|
||||
toSend.pop_front();
|
||||
return c;
|
||||
}
|
||||
else if (connected)
|
||||
return read_pico();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int available() override
|
||||
{
|
||||
if (!toSend.empty())
|
||||
return toSend.size();
|
||||
else if (connected)
|
||||
return pico_available();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void write(u8 data) override
|
||||
{
|
||||
if (connected)
|
||||
write_pico(data);
|
||||
else if (data == '\r' || data == '\n')
|
||||
handleCmd();
|
||||
else
|
||||
recvBuf.push_back(data);
|
||||
}
|
||||
|
||||
private:
|
||||
void handleCmd()
|
||||
{
|
||||
if (recvBuf.empty())
|
||||
return;
|
||||
std::string line(recvBuf.begin(), recvBuf.end());
|
||||
recvBuf.clear();
|
||||
if (line.substr(0, 4) == "ATDT") {
|
||||
send("CONNECT 14400");
|
||||
start_pico();
|
||||
connected = true;
|
||||
sh4_sched_request(schedId, SH4_MAIN_CLOCK / 60);
|
||||
}
|
||||
else if (line.substr(0, 2) == "AT")
|
||||
send("OK");
|
||||
}
|
||||
|
||||
void send(const std::string& l)
|
||||
{
|
||||
toSend.insert(toSend.end(), l.begin(), l.end());
|
||||
toSend.push_back('\n');
|
||||
serial_updateStatusRegister();
|
||||
}
|
||||
|
||||
static int schedCallback(int tag, int cycles, int lag)
|
||||
{
|
||||
serial_updateStatusRegister();
|
||||
return SH4_MAIN_CLOCK / 60;
|
||||
}
|
||||
|
||||
std::deque<char> toSend;
|
||||
std::vector<char> recvBuf;
|
||||
bool connected = false;
|
||||
int schedId = -1;
|
||||
};
|
||||
|
||||
static std::unique_ptr<ModemEmu> modemEmu;
|
||||
|
||||
void serialModemInit() {
|
||||
modemEmu = std::make_unique<ModemEmu>();
|
||||
}
|
||||
|
||||
void serialModemTerm() {
|
||||
modemEmu.reset();
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
Copyright 2023 flyinghead
|
||||
|
||||
This file is part of Flycast.
|
||||
|
||||
Flycast is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Flycast is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
void serialModemInit();
|
||||
void serialModemTerm();
|
|
@ -315,6 +315,15 @@ int read_pico()
|
|||
}
|
||||
}
|
||||
|
||||
int pico_available()
|
||||
{
|
||||
in_buffer_lock.lock();
|
||||
int len = in_buffer.size();
|
||||
in_buffer_lock.unlock();
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static void read_from_dc_socket(pico_socket *pico_sock, sock_t nat_sock)
|
||||
{
|
||||
char buf[1510];
|
||||
|
@ -514,14 +523,14 @@ static void udp_callback(uint16_t ev, pico_socket *s)
|
|||
// Daytona USA
|
||||
if (msginfo.local_port == 0x2F2F && buf[0] == 0x20 && buf[2] == 0x42)
|
||||
{
|
||||
if (buf[1] == 0x2b && r >= 37 + sizeof(public_ip.addr))
|
||||
if (buf[1] == 0x2b && r >= 37 + (int)sizeof(public_ip.addr))
|
||||
{
|
||||
// Start session packet
|
||||
char *p = &buf[37];
|
||||
if (memcmp(p, &dcaddr.addr, sizeof(dcaddr.addr)) == 0)
|
||||
memcpy(p, &public_ip.addr, sizeof(public_ip.addr));
|
||||
}
|
||||
else if (buf[1] == 0x15 && r >= 14 + sizeof(public_ip.addr))
|
||||
else if (buf[1] == 0x15 && r >= 14 + (int)sizeof(public_ip.addr))
|
||||
{
|
||||
char *p = &buf[5];
|
||||
if (memcmp(p, &dcaddr.addr, sizeof(dcaddr.addr)) == 0)
|
||||
|
@ -657,7 +666,7 @@ static void read_native_sockets()
|
|||
memset(&src_addr, 0, addr_len);
|
||||
r = (int)recvfrom(it->second, buf, sizeof(buf), 0, (sockaddr *)&src_addr, &addr_len);
|
||||
// filter out messages coming from ourselves (happens for broadcasts)
|
||||
if (r > 0 && !is_local_address(src_addr.sin_addr.s_addr))
|
||||
if (r > 0 && (it->first != src_addr.sin_port || !is_local_address(src_addr.sin_addr.s_addr)))
|
||||
{
|
||||
msginfo.dev = pico_dev;
|
||||
msginfo.tos = 0;
|
||||
|
|
|
@ -24,6 +24,7 @@ bool start_pico();
|
|||
void stop_pico();
|
||||
void write_pico(u8 b);
|
||||
int read_pico();
|
||||
int pico_available();
|
||||
|
||||
void pico_receive_eth_frame(const u8 *frame, u32 size);
|
||||
// implemented in bba
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue