mirror of
https://github.com/afska/gba-link-connection.git
synced 2026-09-08 17:07:33 -05:00
Refactoring and trying out multiple clients
This commit is contained in:
@@ -4,7 +4,14 @@
|
||||
// (0) Include the header
|
||||
#include "../../_lib/LinkWireless.h"
|
||||
|
||||
void activate();
|
||||
void host();
|
||||
void connect();
|
||||
void messageLoop(bool acceptNewClients);
|
||||
void log(std::string text);
|
||||
void waitFor(u16 key);
|
||||
void vBlankWait();
|
||||
void hang();
|
||||
|
||||
// (1) Create a LinkWireless instance
|
||||
LinkWireless* linkWireless = new LinkWireless();
|
||||
@@ -14,9 +21,6 @@ void init() {
|
||||
|
||||
REG_DISPCNT = DCNT_MODE0 | DCNT_BG0;
|
||||
tte_init_se_default(0, BG_CBB(0) | BG_SBB(31));
|
||||
|
||||
// (2) Initialize the library
|
||||
// linkWireless->activate(); // TODO: RECOVER
|
||||
}
|
||||
|
||||
int main() {
|
||||
@@ -27,164 +31,200 @@ int main() {
|
||||
bool connecting = false;
|
||||
|
||||
while (true) {
|
||||
// std::string output = "";
|
||||
u16 keys = ~REG_KEYS & KEY_ANY;
|
||||
|
||||
if ((keys & KEY_START) && !activating) {
|
||||
log("Trying...");
|
||||
activating = true;
|
||||
if (linkWireless->activate())
|
||||
log("Activated! :)");
|
||||
else
|
||||
log("Activation failed! :(");
|
||||
}
|
||||
log("START = Activate\nL = Host\nR = Connect");
|
||||
|
||||
// START = Activate
|
||||
if ((keys & KEY_START) && !activating) {
|
||||
activating = true;
|
||||
activate();
|
||||
}
|
||||
if (activating && !(keys & KEY_START))
|
||||
activating = false;
|
||||
|
||||
// L = Host
|
||||
if ((keys & KEY_L) && !hosting) {
|
||||
log("Hosting...");
|
||||
hosting = true;
|
||||
if (linkWireless->host(std::vector<u32>{0x0c020002, 0x00005ce1,
|
||||
0x00000000, 0x09000040,
|
||||
0xc1cfc8cd, 0x00ffccbb})) {
|
||||
log("Hosting ok. Listening...");
|
||||
u16 newId = 0;
|
||||
do {
|
||||
newId = linkWireless->getNewConnectionId();
|
||||
log("Hosting ok. " + std::to_string(newId) + " Listening... ");
|
||||
} while (newId == 0 || newId == 1);
|
||||
log("CONNECTED! " + std::to_string(newId));
|
||||
|
||||
u32 i = 50;
|
||||
bool sending = false;
|
||||
|
||||
// TODO: DEDUP
|
||||
while (true) {
|
||||
keys = ~REG_KEYS & KEY_ANY;
|
||||
|
||||
if (!sending && (keys & KEY_A)) {
|
||||
sending = true;
|
||||
linkWireless->sendData(std::vector<u32>{i});
|
||||
i++;
|
||||
}
|
||||
|
||||
if (sending && !(keys & KEY_A))
|
||||
sending = false;
|
||||
|
||||
std::vector<u32> receivedData = std::vector<u32>{};
|
||||
if (!linkWireless->receiveData(receivedData)) {
|
||||
log("ERROR RECEIVING!");
|
||||
while (true)
|
||||
;
|
||||
}
|
||||
if (receivedData.size() > 0)
|
||||
log("RECEIVED: " + std::to_string(receivedData[0]));
|
||||
|
||||
while (REG_VCOUNT >= 160)
|
||||
; // wait till VDraw
|
||||
while (REG_VCOUNT < 160)
|
||||
; // wait till VBlank
|
||||
}
|
||||
} else {
|
||||
log("Hosting error");
|
||||
while (true)
|
||||
;
|
||||
}
|
||||
host();
|
||||
}
|
||||
|
||||
if (hosting && !(keys & KEY_L))
|
||||
hosting = false;
|
||||
|
||||
// R = Connect
|
||||
if (!connecting && (keys & KEY_R)) {
|
||||
log("Searching...");
|
||||
connecting = true;
|
||||
std::vector<u32> data;
|
||||
if (linkWireless->getBroadcasts(data)) {
|
||||
std::string str =
|
||||
"Press select to conn " + std::to_string(data.size()) + "\n";
|
||||
for (u32& dat : data)
|
||||
str += std::to_string(dat) + "\n";
|
||||
log(str);
|
||||
|
||||
if (data.size() > 0) {
|
||||
do {
|
||||
keys = ~REG_KEYS & KEY_ANY;
|
||||
} while (!(keys & KEY_SELECT));
|
||||
|
||||
if (!linkWireless->connect((u16)data[0])) {
|
||||
log("CONNECT FAILED!");
|
||||
while (true)
|
||||
;
|
||||
}
|
||||
|
||||
u16 idid = 0;
|
||||
do {
|
||||
idid = linkWireless->isFinishedConnect();
|
||||
} while (idid <= 1);
|
||||
|
||||
log("HAVE ID! PRESS SEL! " + std::to_string(idid));
|
||||
|
||||
do {
|
||||
keys = ~REG_KEYS & KEY_ANY;
|
||||
} while (!(keys & KEY_SELECT));
|
||||
|
||||
u16 asd = linkWireless->finishConnection();
|
||||
if (asd == 0) {
|
||||
log("FINISH CONNECT FAILED!");
|
||||
while (true)
|
||||
;
|
||||
}
|
||||
|
||||
u32 i = 50;
|
||||
bool sending = false;
|
||||
log("CONNECTED! " + std::to_string(asd));
|
||||
// TODO: DEDUP
|
||||
while (true) {
|
||||
keys = ~REG_KEYS & KEY_ANY;
|
||||
|
||||
if (!sending && (keys & KEY_A)) {
|
||||
sending = true;
|
||||
linkWireless->sendData(std::vector<u32>{i});
|
||||
i++;
|
||||
}
|
||||
|
||||
if (sending && !(keys & KEY_A))
|
||||
sending = false;
|
||||
|
||||
std::vector<u32> receivedData = std::vector<u32>{};
|
||||
if (!linkWireless->receiveData(receivedData)) {
|
||||
log("ERROR RECEIVING!");
|
||||
while (true)
|
||||
;
|
||||
}
|
||||
if (receivedData.size() > 0)
|
||||
log("RECEIVED: " + std::to_string(receivedData[0]));
|
||||
|
||||
while (REG_VCOUNT >= 160)
|
||||
; // wait till VDraw
|
||||
while (REG_VCOUNT < 160)
|
||||
; // wait till VBlank
|
||||
}
|
||||
}
|
||||
} else
|
||||
log("Search failed :(");
|
||||
connect();
|
||||
}
|
||||
|
||||
if (connecting && !(keys & KEY_R))
|
||||
connecting = false;
|
||||
|
||||
while (REG_VCOUNT >= 160)
|
||||
; // wait till VDraw
|
||||
while (REG_VCOUNT < 160)
|
||||
; // wait till VBlank
|
||||
vBlankWait();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void activate() {
|
||||
log("Trying...");
|
||||
|
||||
if (linkWireless->activate())
|
||||
log("Activated!");
|
||||
else
|
||||
log("Activation failed! :(");
|
||||
|
||||
hang();
|
||||
}
|
||||
|
||||
void host() {
|
||||
log("Hosting...");
|
||||
|
||||
if (!linkWireless->host(std::vector<u32>{0x0c020002, 0x00005ce1, 0x00000000,
|
||||
0x09000040, 0xc1cfc8cd,
|
||||
0x00ffccbb})) {
|
||||
log("Hosting failed :(");
|
||||
hang();
|
||||
return;
|
||||
}
|
||||
|
||||
log("Listening...");
|
||||
|
||||
LinkWireless::ClientIdResponses response;
|
||||
do {
|
||||
response = linkWireless->acceptConnection();
|
||||
if (!response.success) {
|
||||
log("Accept failed :(");
|
||||
hang();
|
||||
return;
|
||||
}
|
||||
} while (response.clientIds[0] == 0);
|
||||
|
||||
log("Connected! " + std::to_string(response.clientIds[0]));
|
||||
|
||||
messageLoop(true);
|
||||
}
|
||||
|
||||
void connect() {
|
||||
log("Searching...");
|
||||
|
||||
std::vector<u32> broadcastData;
|
||||
if (!linkWireless->getBroadcasts(broadcastData)) {
|
||||
log("Search failed :(");
|
||||
hang();
|
||||
return;
|
||||
}
|
||||
|
||||
std::string str = "Press SELECT to connect\n";
|
||||
for (u32& number : broadcastData)
|
||||
str += std::to_string(number) + "\n";
|
||||
log(str);
|
||||
|
||||
if (broadcastData.size() == 0) {
|
||||
log("Nothing found :(");
|
||||
hang();
|
||||
return;
|
||||
}
|
||||
|
||||
waitFor(KEY_SELECT);
|
||||
|
||||
if (!linkWireless->connect((u16)broadcastData[0])) {
|
||||
log("Connect failed :(");
|
||||
hang();
|
||||
return;
|
||||
}
|
||||
|
||||
LinkWireless::ClientIdResponse response1;
|
||||
do {
|
||||
response1 = linkWireless->checkConnection();
|
||||
if (!response1.success) {
|
||||
log("Check connection failed :(");
|
||||
hang();
|
||||
return;
|
||||
}
|
||||
|
||||
log("Checking: " + std::to_string(response1.clientId));
|
||||
} while (response1.clientId == 0);
|
||||
|
||||
log("Assigned id (press SELECT):\n" + std::to_string(response1.clientId));
|
||||
|
||||
waitFor(KEY_SELECT);
|
||||
|
||||
auto response2 = linkWireless->finishConnection();
|
||||
if (!response2.success) {
|
||||
log("Finish connection failed :(");
|
||||
hang();
|
||||
return;
|
||||
}
|
||||
if (response2.clientId != response1.clientId) {
|
||||
log("Assigned IDs don't match :(");
|
||||
hang();
|
||||
return;
|
||||
}
|
||||
|
||||
log("Connected! " + std::to_string(response2.clientId));
|
||||
|
||||
messageLoop(false);
|
||||
}
|
||||
|
||||
void messageLoop(bool acceptNewClients) {
|
||||
u32 i = 50;
|
||||
bool sending = false;
|
||||
|
||||
while (true) {
|
||||
u16 keys = ~REG_KEYS & KEY_ANY;
|
||||
|
||||
if (!sending && (keys & KEY_A)) {
|
||||
sending = true;
|
||||
linkWireless->sendData(std::vector<u32>{1, i});
|
||||
i++;
|
||||
}
|
||||
if (sending && !(keys & KEY_A))
|
||||
sending = false;
|
||||
|
||||
if (acceptNewClients) {
|
||||
auto newConnection = linkWireless->acceptConnection();
|
||||
if (!newConnection.success) {
|
||||
log("Accept failed :(");
|
||||
hang();
|
||||
return;
|
||||
}
|
||||
if (newConnection.clientIds.size() > 1)
|
||||
log("New connection: " + std::to_string(newConnection.clientIds[1]));
|
||||
}
|
||||
|
||||
std::vector<u32> receivedData = std::vector<u32>{};
|
||||
if (!linkWireless->receiveData(receivedData)) {
|
||||
log("Receive failed :(");
|
||||
hang();
|
||||
return;
|
||||
}
|
||||
if (receivedData.size() > 1)
|
||||
log("<<< " + std::to_string(receivedData[1]));
|
||||
|
||||
vBlankWait();
|
||||
}
|
||||
}
|
||||
|
||||
void log(std::string text) {
|
||||
tte_erase_screen();
|
||||
tte_write("#{P:0,0}");
|
||||
tte_write(text.c_str());
|
||||
}
|
||||
|
||||
void waitFor(u16 key) {
|
||||
u16 keys;
|
||||
do {
|
||||
keys = ~REG_KEYS & KEY_ANY;
|
||||
} while (!(keys & key));
|
||||
}
|
||||
|
||||
void vBlankWait() {
|
||||
while (REG_VCOUNT >= 160)
|
||||
; // wait till VDraw
|
||||
while (REG_VCOUNT < 160)
|
||||
; // wait till VBlank
|
||||
}
|
||||
|
||||
void hang() {
|
||||
waitFor(KEY_DOWN);
|
||||
}
|
||||
@@ -30,10 +30,9 @@
|
||||
#include "LinkGPIO.h"
|
||||
#include "LinkSPI.h"
|
||||
|
||||
// TODO: AVOID response.responses, use result
|
||||
|
||||
#define LINK_WIRELESS_PING_WAIT 50
|
||||
#define LINK_WIRELESS_TRANSFER_WAIT 15
|
||||
#define LINK_WIRELESS_BROADCAST_SEARCH_WAIT ((160 + 68) * 60)
|
||||
#define LINK_WIRELESS_TIMEOUT 100
|
||||
#define LINK_WIRELESS_LOGIN_STEPS 9
|
||||
#define LINK_WIRELESS_BROADCAST_SIZE 6
|
||||
@@ -59,6 +58,14 @@ const u16 LINK_WIRELESS_LOGIN_PARTS[] = {0x494e, 0x494e, 0x544e, 0x544e, 0x4e45,
|
||||
|
||||
class LinkWireless {
|
||||
public:
|
||||
struct ClientIdResponse {
|
||||
bool success = false;
|
||||
u16 clientId = 0;
|
||||
};
|
||||
struct ClientIdResponses {
|
||||
bool success = false;
|
||||
std::vector<u32> clientIds = std::vector<u32>{0}; // TODO: IMPROVE
|
||||
};
|
||||
std::function<void(std::string)> debug; // TODO: REMOVE
|
||||
|
||||
bool isActive() { return isEnabled; }
|
||||
@@ -87,13 +94,18 @@ class LinkWireless {
|
||||
sendCommand(LINK_WIRELESS_COMMAND_START_HOST).success;
|
||||
}
|
||||
|
||||
u16 getNewConnectionId() {
|
||||
auto response = sendCommand(0x1a);
|
||||
if (!response.success)
|
||||
return 0; // TODO: PROPER RETURN TYPE
|
||||
ClientIdResponses acceptConnection() {
|
||||
auto result = sendCommand(LINK_WIRELESS_COMMAND_IS_CONNECT_ATTEMPT);
|
||||
|
||||
return response.responses.size() > 0 ? (u16)response.responses[0]
|
||||
: 1; // TODO: FIGURE OUT MULTIPLE IDS
|
||||
ClientIdResponses response;
|
||||
if (!result.success)
|
||||
return response;
|
||||
response.success = true;
|
||||
if (result.responses.size() == 0)
|
||||
return response;
|
||||
response.clientIds = result.responses;
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
bool connect(u16 remoteId) {
|
||||
@@ -102,26 +114,35 @@ class LinkWireless {
|
||||
.success;
|
||||
}
|
||||
|
||||
u16 isFinishedConnect() {
|
||||
auto response = sendCommand(LINK_WIRELESS_COMMAND_IS_FINISHED_CONNECT);
|
||||
if (!response.success || response.responses.size() == 0)
|
||||
return 0; // TODO: PROPER RETURN TYPE
|
||||
ClientIdResponse checkConnection() {
|
||||
auto result = sendCommand(LINK_WIRELESS_COMMAND_IS_FINISHED_CONNECT);
|
||||
|
||||
if (msB32(response.responses[0]) > 0)
|
||||
return 1;
|
||||
ClientIdResponse response;
|
||||
if (!result.success)
|
||||
return response;
|
||||
response.success = true;
|
||||
if (result.responses.size() == 0 || msB32(result.responses[0]) > 0)
|
||||
return response;
|
||||
response.clientId = (u16)result.responses[0];
|
||||
|
||||
return (u16)response.responses[0];
|
||||
return response;
|
||||
}
|
||||
|
||||
u16 finishConnection() {
|
||||
auto response = sendCommand(LINK_WIRELESS_COMMAND_FINISH_CONNECTION);
|
||||
if (!response.success || response.responses.size() == 0)
|
||||
return 0; // TODO: PROPER RETURN TYPE
|
||||
ClientIdResponse finishConnection() {
|
||||
auto result = sendCommand(LINK_WIRELESS_COMMAND_FINISH_CONNECTION);
|
||||
|
||||
return (u16)response.responses[0];
|
||||
ClientIdResponse response;
|
||||
if (!result.success)
|
||||
return response;
|
||||
response.success = true;
|
||||
if (result.responses.size() == 0)
|
||||
return response;
|
||||
response.clientId = (u16)result.responses[0];
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
// TODO: 0 IS NOT A VALID VALUE
|
||||
// TODO: CHECK RANGES
|
||||
bool sendData(std::vector<u32> data) {
|
||||
return sendCommand(LINK_WIRELESS_COMMAND_SEND_DATA, data).success;
|
||||
}
|
||||
@@ -142,19 +163,13 @@ class LinkWireless {
|
||||
if (!sendCommand(LINK_WIRELESS_COMMAND_BROADCAST_READ_START).success)
|
||||
return false;
|
||||
|
||||
wait(228 * 60); // TODO: NEEDED INDEED!
|
||||
wait(LINK_WIRELESS_BROADCAST_SEARCH_WAIT);
|
||||
|
||||
auto result = sendCommand(LINK_WIRELESS_COMMAND_BROADCAST_READ_END);
|
||||
data = result.responses;
|
||||
return result.success;
|
||||
}
|
||||
|
||||
// bool read(std::vector<u32>& data) {
|
||||
// auto result = sendCommand(LINK_WIRELESS_COMMAND_BROADCAST_READ);
|
||||
// data = result.responses;
|
||||
// return result.success;
|
||||
// }
|
||||
|
||||
~LinkWireless() {
|
||||
delete linkSPI;
|
||||
delete linkGPIO;
|
||||
|
||||
Reference in New Issue
Block a user