mirror of
https://github.com/afska/gba-link-connection.git
synced 2026-04-25 08:07:59 -05:00
Stop using std::vector in LinkWireless
This commit is contained in:
parent
455bccb2fc
commit
2a29d6f680
|
|
@ -176,13 +176,13 @@ Name | Return type | Description
|
|||
`activate()` | **bool** | Activates the library. When an adapter is connected, it changes the state to `AUTHENTICATED`. It can also be used to disconnect or reset the adapter.
|
||||
`deactivate()` | - | Deactivates the library.
|
||||
`serve([gameName], [userName])` | **bool** | Starts broadcasting a server and changes the state to `SERVING`. You can, optionally, provide a `gameName` (max `14` characters) and `userName` (max `8` characters) that games will be able to read.
|
||||
`getServers(servers, [onWait])` | **bool** | Fills the `servers` vector with all the currently broadcasting servers. This action takes 1 second to complete, but you can optionally provide an `onWait()` function which will be invoked each time VBlank starts.
|
||||
`getServers(servers, [onWait])` | **bool** | Fills the `servers` array with all the currently broadcasting servers. This action takes 1 second to complete, but you can optionally provide an `onWait()` function which will be invoked each time VBlank starts.
|
||||
`getServersAsyncStart()` | **bool** | Starts looking for broadcasting servers and changes the state to `SEARCHING`. After this, call `getServersAsyncEnd(...)` 1 second later.
|
||||
`getServersAsyncEnd(servers)` | **bool** | Fills the `servers` vector with all the currently broadcasting servers. Changes the state to `AUTHENTICATED` again.
|
||||
`getServersAsyncEnd(servers)` | **bool** | Fills the `servers` array with all the currently broadcasting servers. Changes the state to `AUTHENTICATED` again.
|
||||
`connect(serverId)` | **bool** | Starts a connection with `serverId` and changes the state to `CONNECTING`.
|
||||
`keepConnecting()` | **bool** | When connecting, this needs to be called until the state is `CONNECTED`. It assigns a player id. Keep in mind that `isConnected()` and `playerCount()` won't be updated until the first message from server arrives.
|
||||
`send(data)` | **bool** | Enqueues `data` to be sent to other nodes.
|
||||
`receive(messages)` | **bool** | Fills the `messages` vector with incoming messages, forwarding if needed.
|
||||
`receive(messages)` | **bool** | Fills the `messages` array with incoming messages, forwarding if needed.
|
||||
`getState()` | **LinkWireless::State** | Returns the current state (one of `LinkWireless::State::NEEDS_RESET`, `LinkWireless::State::AUTHENTICATED`, `LinkWireless::State::SEARCHING`, `LinkWireless::State::SERVING`, `LinkWireless::State::CONNECTING`, or `LinkWireless::State::CONNECTED`).
|
||||
`isConnected()` | **bool** | Returns true if the player count is higher than 1.
|
||||
`isSessionActive()` | **bool** | Returns true if the state is `SERVING` or `CONNECTED`.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include <tonc.h>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "../../_lib/interrupt.h"
|
||||
|
||||
// (0) Include the header
|
||||
|
|
@ -172,17 +173,21 @@ void connect() {
|
|||
};
|
||||
|
||||
// (5) Connect to a server
|
||||
std::vector<LinkWireless::Server> servers;
|
||||
LinkWireless::Server servers[LINK_WIRELESS_MAX_SERVERS];
|
||||
linkWireless->getServers(servers, animate);
|
||||
CHECK_ERRORS("Search failed :(")
|
||||
|
||||
if (servers.size() == 0) {
|
||||
if (servers[0].id == LINK_WIRELESS_END) {
|
||||
log("Nothing found :(");
|
||||
hang();
|
||||
return;
|
||||
} else {
|
||||
std::string str = "Press START to connect\n(first ID will be used)\n\n";
|
||||
for (auto& server : servers) {
|
||||
for (u32 i = 0; i < LINK_WIRELESS_MAX_SERVERS; i++) {
|
||||
auto server = servers[i];
|
||||
if (server.id == LINK_WIRELESS_END)
|
||||
break;
|
||||
|
||||
str += std::to_string(server.id) + "\n";
|
||||
if (server.gameName.length() > 0)
|
||||
str += " -> game: " + server.gameName + "\n";
|
||||
|
|
@ -285,10 +290,14 @@ void messageLoop() {
|
|||
sending = false;
|
||||
|
||||
// (7) Receive data
|
||||
auto messages = std::vector<LinkWireless::Message>{};
|
||||
LinkWireless::Message messages[LINK_WIRELESS_MAX_TRANSFER_LENGTH];
|
||||
linkWireless->receive(messages);
|
||||
if (messages.size() > 0) {
|
||||
for (auto& message : messages) {
|
||||
if (messages[0].packetId != LINK_WIRELESS_END) {
|
||||
for (u32 i = 0; i < LINK_WIRELESS_MAX_TRANSFER_LENGTH; i++) {
|
||||
auto message = messages[i];
|
||||
if (message.packetId == LINK_WIRELESS_END)
|
||||
break;
|
||||
|
||||
u32 expected = counters[message.playerId] + 1;
|
||||
|
||||
counters[message.playerId] = message.data;
|
||||
|
|
@ -299,7 +308,7 @@ void messageLoop() {
|
|||
lastLostPacketPlayerId = message.playerId;
|
||||
lastLostPacketExpected = expected;
|
||||
lastLostPacketReceived = message.data;
|
||||
lastLostPacketReceivedPacketId = message._packetId;
|
||||
lastLostPacketReceivedPacketId = message.packetId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@
|
|||
|
||||
#include <tonc_core.h>
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
#include "LinkCable.h"
|
||||
#include "LinkWireless.h"
|
||||
|
||||
|
|
@ -260,7 +259,6 @@ class LinkUniversal {
|
|||
};
|
||||
|
||||
std::queue<u16> incomingMessages[LINK_UNIVERSAL_MAX_PLAYERS];
|
||||
std::vector<LinkWireless::Message> tmpMessages;
|
||||
LinkCable* linkCable;
|
||||
LinkWireless* linkWireless;
|
||||
Config config;
|
||||
|
|
@ -280,11 +278,16 @@ class LinkUniversal {
|
|||
}
|
||||
|
||||
void receiveWirelessMessages() {
|
||||
tmpMessages.clear();
|
||||
linkWireless->receive(tmpMessages);
|
||||
LinkWireless::Message messages[LINK_WIRELESS_MAX_TRANSFER_LENGTH];
|
||||
linkWireless->receive(messages);
|
||||
|
||||
for (u32 i = 0; i < LINK_WIRELESS_MAX_TRANSFER_LENGTH; i++) {
|
||||
auto message = messages[i];
|
||||
if (message.packetId == LINK_WIRELESS_END)
|
||||
break;
|
||||
|
||||
for (auto& message : tmpMessages)
|
||||
push(incomingMessages[message.playerId], message.data);
|
||||
}
|
||||
}
|
||||
|
||||
bool autoDiscoverWirelessConnections() {
|
||||
|
|
@ -330,14 +333,17 @@ class LinkUniversal {
|
|||
}
|
||||
|
||||
bool tryConnectOrServeWirelessSession() {
|
||||
std::vector<LinkWireless::Server> servers;
|
||||
LinkWireless::Server servers[LINK_WIRELESS_MAX_SERVERS];
|
||||
if (!linkWireless->getServersAsyncEnd(servers))
|
||||
return false;
|
||||
|
||||
u32 maxRandomNumber = 0;
|
||||
u32 serverIndex = 0;
|
||||
for (u32 i = 0; i < servers.size(); i++) {
|
||||
for (u32 i = 0; i < LINK_WIRELESS_MAX_SERVERS; i++) {
|
||||
auto server = servers[i];
|
||||
if (server.id == LINK_WIRELESS_END)
|
||||
break;
|
||||
|
||||
u32 randomNumber = std::stoi(server.userName);
|
||||
|
||||
if (server.gameName == config.gameName &&
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@
|
|||
// // `currentPlayerId()` should return 0
|
||||
// // `playerCount()` should return the number of active consoles
|
||||
// - 5) Connect to a server:
|
||||
// std::vector<LinkWireless::Server> servers;
|
||||
// LinkWireless::Server servers[LINK_WIRELESS_MAX_SERVERS];
|
||||
// linkWireless->getServers(servers);
|
||||
// if (servers.empty()) return;
|
||||
// if (servers[0].id == LINK_WIRELESS_END) return;
|
||||
//
|
||||
// linkWireless->connect(servers[0].id);
|
||||
// while (linkWireless->getState() == LinkWireless::State::CONNECTING)
|
||||
|
|
@ -35,9 +35,9 @@
|
|||
// - 6) Send data:
|
||||
// linkWireless->send(0x1234);
|
||||
// - 7) Receive data:
|
||||
// auto messages = std::vector<LinkWireless::Message>{};
|
||||
// LinkWireless::Message messages[LINK_WIRELESS_MAX_TRANSFER_LENGTH];
|
||||
// linkWireless->receive(messages);
|
||||
// if (messages.size() > 0) {
|
||||
// if (messages[0].packetId != LINK_WIRELESS_END) {
|
||||
// // ...
|
||||
// }
|
||||
// - 8) Disconnect:
|
||||
|
|
@ -54,7 +54,6 @@
|
|||
|
||||
#include <tonc_core.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "LinkGPIO.h"
|
||||
#include "LinkSPI.h"
|
||||
|
||||
|
|
@ -68,6 +67,7 @@
|
|||
|
||||
#define LINK_WIRELESS_MAX_PLAYERS 5
|
||||
#define LINK_WIRELESS_MIN_PLAYERS 2
|
||||
#define LINK_WIRELESS_END 0
|
||||
#define LINK_WIRELESS_DEFAULT_TIMEOUT 8
|
||||
#define LINK_WIRELESS_DEFAULT_REMOTE_TIMEOUT 10
|
||||
#define LINK_WIRELESS_DEFAULT_INTERVAL 50
|
||||
|
|
@ -94,6 +94,11 @@
|
|||
#define LINK_WIRELESS_BROADCAST_LENGTH 6
|
||||
#define LINK_WIRELESS_BROADCAST_RESPONSE_LENGTH \
|
||||
(1 + LINK_WIRELESS_BROADCAST_LENGTH)
|
||||
#define LINK_WIRELESS_MAX_TRANSFER_LENGTH \
|
||||
LINK_WIRELESS_MAX_SERVER_TRANSFER_LENGTH
|
||||
#define LINK_WIRELESS_MAX_SERVERS \
|
||||
(LINK_WIRELESS_MAX_COMMAND_RESPONSE_LENGTH / \
|
||||
LINK_WIRELESS_BROADCAST_RESPONSE_LENGTH)
|
||||
#define LINK_WIRELESS_COMMAND_HELLO 0x10
|
||||
#define LINK_WIRELESS_COMMAND_SETUP 0x17
|
||||
#define LINK_WIRELESS_COMMAND_BROADCAST 0x16
|
||||
|
|
@ -157,14 +162,14 @@ class LinkWireless {
|
|||
};
|
||||
|
||||
struct Message {
|
||||
u32 _packetId = 0;
|
||||
u32 packetId = 0;
|
||||
|
||||
u16 data;
|
||||
u8 playerId = 0;
|
||||
};
|
||||
|
||||
struct Server {
|
||||
u16 id;
|
||||
u16 id = 0;
|
||||
std::string gameName;
|
||||
std::string userName;
|
||||
};
|
||||
|
|
@ -251,12 +256,12 @@ class LinkWireless {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool getServers(std::vector<Server>& servers) {
|
||||
bool getServers(Server servers[]) {
|
||||
return getServers(servers, []() {});
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
bool getServers(std::vector<Server>& servers, F onWait) {
|
||||
bool getServers(Server servers[], F onWait) {
|
||||
if (!getServersAsyncStart())
|
||||
return false;
|
||||
|
||||
|
|
@ -289,7 +294,7 @@ class LinkWireless {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool getServersAsyncEnd(std::vector<Server>& servers) {
|
||||
bool getServersAsyncEnd(Server servers[]) {
|
||||
LINK_WIRELESS_RESET_IF_NEEDED
|
||||
if (state != SEARCHING) {
|
||||
lastError = WRONG_STATE;
|
||||
|
|
@ -331,7 +336,7 @@ class LinkWireless {
|
|||
recoverName(server.userName, result.responses[start + 5]);
|
||||
recoverName(server.userName, result.responses[start + 6]);
|
||||
|
||||
servers.push_back(server);
|
||||
servers[i] = server;
|
||||
}
|
||||
|
||||
state = AUTHENTICATED;
|
||||
|
|
@ -427,7 +432,7 @@ class LinkWireless {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool receive(std::vector<Message>& messages) {
|
||||
bool receive(Message messages[]) {
|
||||
if (!isEnabled || state == NEEDS_RESET || !isSessionActive())
|
||||
return false;
|
||||
|
||||
|
|
@ -435,10 +440,12 @@ class LinkWireless {
|
|||
isReadingMessages = true;
|
||||
LINK_WIRELESS_BARRIER;
|
||||
|
||||
u32 i = 0;
|
||||
while (!sessionState.incomingMessages.isEmpty()) {
|
||||
auto message = sessionState.incomingMessages.pop();
|
||||
messages.push_back(message);
|
||||
messages[i] = message;
|
||||
forwardMessageIfNeeded(message);
|
||||
i++;
|
||||
}
|
||||
|
||||
LINK_WIRELESS_BARRIER;
|
||||
|
|
@ -481,7 +488,7 @@ class LinkWireless {
|
|||
u32 _nextPendingPacketId() {
|
||||
return sessionState.outgoingMessages.isEmpty()
|
||||
? 0
|
||||
: sessionState.outgoingMessages.peek()._packetId;
|
||||
: sessionState.outgoingMessages.peek().packetId;
|
||||
}
|
||||
|
||||
void _onVBlank() {
|
||||
|
|
@ -803,7 +810,7 @@ class LinkWireless {
|
|||
|
||||
sessionState.outgoingMessages.forEach(
|
||||
[this, maxTransferLength, &lastPacketId](Message message) {
|
||||
u16 header = buildMessageHeader(message.playerId, message._packetId,
|
||||
u16 header = buildMessageHeader(message.playerId, message.packetId,
|
||||
buildChecksum(message.data));
|
||||
u32 rawMessage = buildU32(header, message.data);
|
||||
|
||||
|
|
@ -812,7 +819,7 @@ class LinkWireless {
|
|||
return false;
|
||||
|
||||
addData(rawMessage);
|
||||
lastPacketId = message._packetId;
|
||||
lastPacketId = message.packetId;
|
||||
|
||||
return true;
|
||||
});
|
||||
|
|
@ -851,7 +858,7 @@ class LinkWireless {
|
|||
continue;
|
||||
|
||||
Message message;
|
||||
message._packetId = partialPacketId;
|
||||
message.packetId = partialPacketId;
|
||||
message.data = data;
|
||||
message.playerId = remotePlayerId;
|
||||
|
||||
|
|
@ -878,24 +885,24 @@ class LinkWireless {
|
|||
LINK_WIRELESS_MAX_PACKET_IDS;
|
||||
|
||||
if (config.retransmission && !isConfirmation &&
|
||||
message._packetId != expectedPacketId)
|
||||
message.packetId != expectedPacketId)
|
||||
return false;
|
||||
|
||||
if (!isConfirmation)
|
||||
message._packetId =
|
||||
message.packetId =
|
||||
++sessionState.lastPacketIdFromClients[message.playerId];
|
||||
} else {
|
||||
u32 expectedPacketId = (sessionState.lastPacketIdFromServer + 1) %
|
||||
LINK_WIRELESS_MAX_PACKET_IDS;
|
||||
|
||||
if (config.retransmission && !isConfirmation &&
|
||||
message._packetId != expectedPacketId)
|
||||
message.packetId != expectedPacketId)
|
||||
return false;
|
||||
|
||||
sessionState.playerCount = remotePlayerCount;
|
||||
|
||||
if (!isConfirmation)
|
||||
message._packetId = ++sessionState.lastPacketIdFromServer;
|
||||
message.packetId = ++sessionState.lastPacketIdFromServer;
|
||||
}
|
||||
|
||||
bool isMessageFromCurrentPlayer =
|
||||
|
|
@ -912,7 +919,7 @@ class LinkWireless {
|
|||
void addPingMessageIfNeeded() { // (irq only)
|
||||
if (sessionState.outgoingMessages.isEmpty() && !sessionState.pingSent) {
|
||||
Message pingMessage;
|
||||
pingMessage._packetId = newPacketId();
|
||||
pingMessage.packetId = newPacketId();
|
||||
pingMessage.playerId = sessionState.currentPlayerId;
|
||||
pingMessage.data = LINK_WIRELESS_MSG_PING;
|
||||
sessionState.outgoingMessages.push(pingMessage);
|
||||
|
|
@ -949,7 +956,7 @@ class LinkWireless {
|
|||
}
|
||||
|
||||
bool handleConfirmation(Message confirmation) { // (irq only)
|
||||
u32 confirmationData = (confirmation._packetId << 16) | confirmation.data;
|
||||
u32 confirmationData = (confirmation.packetId << 16) | confirmation.data;
|
||||
|
||||
if (state == CONNECTED) {
|
||||
if (confirmation.playerId == 0 &&
|
||||
|
|
@ -989,7 +996,7 @@ class LinkWireless {
|
|||
|
||||
void removeConfirmedMessages(u32 confirmationData) { // (irq only)
|
||||
while (!sessionState.outgoingMessages.isEmpty() &&
|
||||
sessionState.outgoingMessages.peek()._packetId <= confirmationData)
|
||||
sessionState.outgoingMessages.peek().packetId <= confirmationData)
|
||||
sessionState.outgoingMessages.pop();
|
||||
}
|
||||
|
||||
|
|
@ -1059,7 +1066,7 @@ class LinkWireless {
|
|||
auto message = sessionState.tmpMessagesToSend.pop();
|
||||
|
||||
if (isSessionActive()) {
|
||||
message._packetId = newPacketId();
|
||||
message.packetId = newPacketId();
|
||||
sessionState.outgoingMessages.push(message);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user