ggpo: exchange vf4 cards when starting the session

This commit is contained in:
Flyinghead 2023-05-16 09:43:21 +02:00
parent 8b0add47a2
commit c07f862ef2
3 changed files with 72 additions and 8 deletions

View File

@ -108,3 +108,5 @@ void mcfg_DeserializeDevices(Deserializer& deser);
bool maple_atomiswave_coin_chute(int slot);
void push_vmu_screen(int bus_id, int bus_port, u8* buffer);
void insertRfidCard(int playerNum);
const u8 *getRfidCardData(int playerNum);
void setRfidCardData(int playerNum, u8 *data);

View File

@ -6,6 +6,7 @@
#include "oslib/audiostream.h"
#include "oslib/oslib.h"
#include "hw/aica/sgc_if.h"
#include "cfg/option.h"
#include <zlib.h>
#include <time.h>
@ -1499,14 +1500,24 @@ struct RFIDReaderWriter : maple_base
void OnSetup() override
{
memset(cardData, 0, sizeof(cardData));
transientData = false;
}
std::string getCardPath() const {
return hostfs::getArcadeFlashPath() + "-p" + std::to_string(player_num + 1) + ".card";
}
bool loadCard()
std::string getCardPath() const
{
int playerNum;
if (config::GGPOEnable && !config::ActAsServer)
// Always load P1 card with GGPO to be consistent with P1 inputs being used
playerNum = 1;
else
playerNum = player_num + 1;
return hostfs::getArcadeFlashPath() + "-p" + std::to_string(playerNum) + ".card";
}
void loadCard()
{
if (transientData)
return;
std::string path = getCardPath();
FILE *fp = nowide::fopen(path.c_str(), "rb");
if (fp == nullptr)
@ -1538,12 +1549,12 @@ struct RFIDReaderWriter : maple_base
WARN_LOG(NAOMI, "Truncated or empty card file: %s" ,path.c_str());
fclose(fp);
}
return true;
}
void saveCard() const
{
if (transientData)
return;
std::string path = getCardPath();
FILE *fp = nowide::fopen(path.c_str(), "wb");
if (fp == nullptr)
@ -1579,10 +1590,21 @@ struct RFIDReaderWriter : maple_base
loadCard();
}
const u8 *getCardData() {
loadCard();
return cardData;
}
void setCardData(u8 *data) {
memcpy(cardData, data, sizeof(cardData));
transientData = true;
}
u8 cardData[128];
bool d4Seen = false;
bool cardInserted = false;
bool cardLocked = false;
bool transientData = false;
};
void insertRfidCard(int playerNum)
@ -1592,6 +1614,22 @@ void insertRfidCard(int playerNum)
((RFIDReaderWriter *)mapleDev)->insertCard();
}
void setRfidCardData(int playerNum, u8 *data)
{
maple_device *mapleDev = MapleDevices[1 + playerNum][5];
if (mapleDev != nullptr && mapleDev->get_device_type() == MDT_RFIDReaderWriter)
((RFIDReaderWriter *)mapleDev)->setCardData(data);
}
const u8 *getRfidCardData(int playerNum)
{
maple_device *mapleDev = MapleDevices[1 + playerNum][5];
if (mapleDev != nullptr && mapleDev->get_device_type() == MDT_RFIDReaderWriter)
return ((RFIDReaderWriter *)mapleDev)->getCardData();
else
return nullptr;
}
maple_device* maple_Create(MapleDeviceType type)
{
maple_device* rv=0;

View File

@ -174,13 +174,18 @@ static_assert(BTN_TRIGGER_RIGHT < (1 << 20));
struct GameEvent
{
enum : char {
Chat
Chat,
VF4Card
} type;
union {
struct {
u8 playerNum;
char message[512 - sizeof(playerNum) - sizeof(type)];
} chat;
struct {
u8 playerNum;
u8 data[128];
} card;
} u;
constexpr static int chatMessageLen(int len) { return len - sizeof(u.chat.playerNum) - sizeof(type); }
@ -451,6 +456,10 @@ static void on_message(u8 *msg, int len)
chatCallback(event->u.chat.playerNum, std::string(event->u.chat.message, GameEvent::chatMessageLen(len)));
break;
case GameEvent::VF4Card:
setRfidCardData(event->u.card.playerNum, event->u.card.data);
break;
default:
WARN_LOG(NETWORK, "Unknown app message type %d", event->type);
break;
@ -817,6 +826,21 @@ std::future<bool> startNetwork()
getInput(state);
}
#endif
if (active() && (settings.content.gameId == "VIRTUA FIGHTER 4 JAPAN"
|| settings.content.gameId == "VF4 EVOLUTION JAPAN"
|| settings.content.gameId == "VF4 FINAL TUNED JAPAN"))
{
// Send the local P1 card
const u8 *cardData = getRfidCardData(0);
if (cardData != nullptr)
{
GameEvent event;
event.type = GameEvent::VF4Card;
event.u.card.playerNum = config::ActAsServer ? 0 : 1;
memcpy(event.u.card.data, cardData, sizeof(event.u.card.data));
ggpo_send_message(ggpoSession, &event, sizeof(event.type) + sizeof(event.u.card), true);
}
}
emu.setNetworkState(active());
return active();
});