gba-link-connection/examples/LinkUniversal_basic/src/main.cpp
2025-04-19 08:22:33 -03:00

124 lines
4.3 KiB
C++

// BASIC:
// This example sends the pressed buttons to other players.
// (0) Include the header
#include "../../../lib/LinkUniversal.hpp"
#include "../../_lib/common.h"
#include "../../_lib/interrupt.h"
LinkUniversal* linkUniversal = nullptr;
void init() {
Common::initTTE();
}
int main() {
init();
Common::log(
"LinkUniversal_basic (v8.0.3)\n"
"Press A to start\n\n"
"hold LEFT on start:\n -> force cable\n\n"
"hold RIGHT on start:\n -> force wireless\n\n"
"hold UP on start:\n -> force wireless server\n\n"
"hold DOWN on start:\n -> force wireless client\n\n"
"hold B on start:\n -> set 2 players (wireless)\n\nhold R on start:\n -> "
"restore wireless multiboot");
Common::waitForKey(KEY_A);
u16 initialKeys = ~REG_KEYS & KEY_ANY;
bool forceCable = initialKeys & KEY_LEFT;
bool forceWireless = initialKeys & KEY_RIGHT;
bool forceWirelessServer = initialKeys & KEY_UP;
bool forceWirelessClient = initialKeys & KEY_DOWN;
bool restoreWirelessMultiboot = initialKeys & KEY_R;
LinkUniversal::Protocol protocol =
forceCable ? LinkUniversal::Protocol::CABLE
: forceWireless ? LinkUniversal::Protocol::WIRELESS_AUTO
: forceWirelessServer ? LinkUniversal::Protocol::WIRELESS_SERVER
: forceWirelessClient ? LinkUniversal::Protocol::WIRELESS_CLIENT
: restoreWirelessMultiboot
? LinkUniversal::Protocol::WIRELESS_RESTORE_EXISTING
: LinkUniversal::Protocol::AUTODETECT;
u32 maxPlayers = (initialKeys & KEY_B) ? 2 : LINK_UNIVERSAL_MAX_PLAYERS;
// (1) Create a LinkUniversal instance
linkUniversal = new LinkUniversal(
protocol, "LinkUNI",
(LinkUniversal::CableOptions){
.baudRate = LinkCable::BaudRate::BAUD_RATE_1,
.timeout = LINK_CABLE_DEFAULT_TIMEOUT,
.interval = LINK_CABLE_DEFAULT_INTERVAL,
.sendTimerId = LINK_CABLE_DEFAULT_SEND_TIMER_ID},
(LinkUniversal::WirelessOptions){
.retransmission = true,
.maxPlayers = maxPlayers,
.timeout = restoreWirelessMultiboot ? (u32)1000
: LINK_WIRELESS_DEFAULT_TIMEOUT,
.interval = LINK_WIRELESS_DEFAULT_INTERVAL,
.sendTimerId = LINK_WIRELESS_DEFAULT_SEND_TIMER_ID});
Link::randomSeed = __qran_seed;
// (2) Add the required interrupt service routines
interrupt_init();
interrupt_add(INTR_VBLANK, LINK_UNIVERSAL_ISR_VBLANK);
interrupt_add(INTR_SERIAL, LINK_UNIVERSAL_ISR_SERIAL);
interrupt_add(INTR_TIMER3, LINK_UNIVERSAL_ISR_TIMER);
// B+START+SELECT = SoftReset
REG_KEYCNT = 0b1100000000001110;
interrupt_add(INTR_KEYPAD, Common::ISR_reset);
// (3) Initialize the library
linkUniversal->activate();
u16 data[LINK_UNIVERSAL_MAX_PLAYERS];
for (u32 i = 0; i < LINK_UNIVERSAL_MAX_PLAYERS; i++)
data[i] = 0;
while (true) {
// (4) Sync
linkUniversal->sync();
// (5) Send/read messages
u16 keys = ~REG_KEYS & KEY_ANY;
linkUniversal->send(keys + 1); // (avoid using 0)
std::string output = "";
if (linkUniversal->isConnected()) {
u8 playerCount = linkUniversal->playerCount();
u8 currentPlayerId = linkUniversal->currentPlayerId();
output += "Players: " + std::to_string(playerCount) + "\n";
output += "(";
for (u32 i = 0; i < playerCount; i++) {
while (linkUniversal->canRead(i))
data[i] = linkUniversal->read(i) - 1; // (avoid using 0)
output += std::to_string(data[i]) + (i + 1 == playerCount ? "" : ", ");
}
output += ")\n";
output += "_keys: " + std::to_string(keys) + "\n";
output += "_pID: " + std::to_string(currentPlayerId);
} else {
output +=
"Waiting... [" + std::to_string((int)linkUniversal->getState()) + "]";
output += "<" + std::to_string((int)linkUniversal->getMode()) + ">";
if (linkUniversal->getMode() == LinkUniversal::Mode::LINK_WIRELESS)
output += " (" +
std::to_string((int)linkUniversal->getWirelessState()) + ")";
output += "\n_wait: " + std::to_string(linkUniversal->_getWaitCount());
output += "\n_subW: " + std::to_string(linkUniversal->_getSubWaitCount());
for (u32 i = 0; i < LINK_UNIVERSAL_MAX_PLAYERS; i++)
data[i] = 0;
}
VBlankIntrWait();
Common::log(output);
}
return 0;
}