mirror of
https://github.com/afska/gba-link-connection.git
synced 2026-09-12 19:07:20 -05:00
Dropping tonc dependency in LinkUniversal
This commit is contained in:
@@ -265,6 +265,7 @@ Name | Type | Default | Description
|
||||
`gameName` | **const char\*** | `""` | The game name that will be broadcasted in wireless sessions (max `14` characters). The string must be a null-terminated character array. The library uses this to only connect to servers from the same game.
|
||||
`cableOptions` | **LinkUniversal::CableOptions** | *same as LinkCable* | All the [👾 LinkCable](#-LinkCable) constructor parameters in one *struct*.
|
||||
`wirelessOptions` | **LinkUniversal::WirelessOptions** | *same as LinkWireless* | All the [📻 LinkWireless](#-LinkWireless) constructor parameters in one *struct*.
|
||||
`randomSeed` | **int** | `123` | Random seed used for waits to prevent livelocks. If you use _libtonc_, pass `__qran_seed`.
|
||||
|
||||
You can also change these compile-time constants:
|
||||
- `LINK_UNIVERSAL_MAX_PLAYERS`: to set a maximum number of players. The default value is `5`, but since LinkCable's limit is `4`, you might want to decrease it.
|
||||
|
||||
@@ -49,8 +49,9 @@ int main() {
|
||||
// Sender options
|
||||
if (isSenderMode) {
|
||||
if (result != LinkCableMultiboot::Result::SUCCESS)
|
||||
log("LinkCableMultiboot_demo\n (v7.0.0)\n\nPress START to send the "
|
||||
"ROM...\nPress B to set client mode...");
|
||||
log("LinkCableMultiboot_demo\n (v7.0.0)\n\n"
|
||||
"Press START to send the ROM...\n"
|
||||
"Press B to set client mode...");
|
||||
|
||||
if (keys & KEY_START) {
|
||||
log("Sending... (SELECT to cancel)");
|
||||
|
||||
@@ -52,7 +52,8 @@ LinkUniversal* linkUniversal =
|
||||
.remoteTimeout = LINK_WIRELESS_DEFAULT_REMOTE_TIMEOUT,
|
||||
.interval = LINK_WIRELESS_DEFAULT_INTERVAL,
|
||||
.sendTimerId = LINK_WIRELESS_DEFAULT_SEND_TIMER_ID,
|
||||
.asyncACKTimerId = 0});
|
||||
.asyncACKTimerId = 0},
|
||||
__qran_seed);
|
||||
LinkUniversal* linkConnection = linkUniversal;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#include <tonc.h>
|
||||
#include <string>
|
||||
#include "../../_lib/interrupt.h"
|
||||
|
||||
// BASIC:
|
||||
// This example sends the pressed buttons to other players.
|
||||
|
||||
// (0) Include the header
|
||||
#include "../../../lib/LinkUniversal.hpp"
|
||||
|
||||
#include <tonc.h>
|
||||
#include <string>
|
||||
#include "../../_lib/interrupt.h"
|
||||
|
||||
void log(std::string text);
|
||||
void waitFor(u16 key);
|
||||
|
||||
@@ -21,11 +21,13 @@ void init() {
|
||||
int main() {
|
||||
init();
|
||||
|
||||
log("LinkUniversal_basic (v7.0.0)\n\n\nPress A to start\n\n\nhold LEFT on "
|
||||
"start:\n -> force cable\n\nhold RIGHT on start:\n -> force "
|
||||
"wireless\n\nhold UP on start:\n -> force wireless server\n\nhold DOWN "
|
||||
"on start:\n -> force wireless client\n\nhold B on start:\n -> set 2 "
|
||||
"players (wireless)");
|
||||
log("LinkUniversal_basic (v7.0.0)\n\n\n"
|
||||
"Press A to start\n\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)");
|
||||
waitFor(KEY_A);
|
||||
u16 initialKeys = ~REG_KEYS & KEY_ANY;
|
||||
bool forceCable = initialKeys & KEY_LEFT;
|
||||
@@ -56,7 +58,8 @@ int main() {
|
||||
.remoteTimeout = LINK_WIRELESS_DEFAULT_REMOTE_TIMEOUT,
|
||||
.interval = LINK_WIRELESS_DEFAULT_INTERVAL,
|
||||
.sendTimerId = LINK_WIRELESS_DEFAULT_SEND_TIMER_ID,
|
||||
.asyncACKTimerId = LINK_WIRELESS_DEFAULT_ASYNC_ACK_TIMER_ID});
|
||||
.asyncACKTimerId = LINK_WIRELESS_DEFAULT_ASYNC_ACK_TIMER_ID},
|
||||
__qran_seed);
|
||||
|
||||
// (2) Add the required interrupt service routines
|
||||
interrupt_init();
|
||||
|
||||
@@ -150,7 +150,7 @@ void MultibootScene::load() {
|
||||
log("B: toggle players");
|
||||
log("UP/DOWN: scroll up/down");
|
||||
log("L/R: scroll page up/down");
|
||||
log("UP+L/DOWN+R: scroll to top/bottom");
|
||||
log("UP+L/DOWN+R: scroll top/bottom");
|
||||
log("SELECT: clear");
|
||||
log("---");
|
||||
log("");
|
||||
|
||||
@@ -47,10 +47,12 @@ int main() {
|
||||
|
||||
start:
|
||||
// Options
|
||||
log("LinkWireless_demo (v7.0.0)\n\n\n\nPress A to start\n\n\n\n\nhold LEFT "
|
||||
"on start:\n -> disable forwarding\n\nhold UP on start:\n -> disable "
|
||||
"retransmission\n\nhold B on start:\n -> set 2 players\n\nhold START on "
|
||||
"start:\n -> async ACK");
|
||||
log("LinkWireless_demo (v7.0.0)\n\n\n\n"
|
||||
"Press A to start\n\n\n\n\n"
|
||||
"hold LEFT on start:\n -> disable forwarding\n\n"
|
||||
"hold UP on start:\n -> disable retransmission\n\n"
|
||||
"hold B on start:\n -> set 2 players\n\n"
|
||||
"hold START on start:\n -> async ACK");
|
||||
waitFor(KEY_A);
|
||||
u16 initialKeys = ~REG_KEYS & KEY_ANY;
|
||||
forwarding = !(initialKeys & KEY_LEFT);
|
||||
|
||||
@@ -45,9 +45,8 @@
|
||||
// (they mean 'disconnected' and 'no data' respectively)
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
#include <tonc_bios.h>
|
||||
#include <tonc_core.h>
|
||||
#include <tonc_math.h>
|
||||
#include "_link_common.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
#include "LinkCable.hpp"
|
||||
#include "LinkWireless.hpp"
|
||||
@@ -58,23 +57,26 @@
|
||||
// Game ID Filter. Default = 0 (no filter)
|
||||
#define LINK_UNIVERSAL_GAME_ID_FILTER 0
|
||||
|
||||
#define LINK_UNIVERSAL_DISCONNECTED LINK_CABLE_DISCONNECTED
|
||||
#define LINK_UNIVERSAL_NO_DATA LINK_CABLE_NO_DATA
|
||||
#define LINK_UNIVERSAL_MAX_ROOM_NUMBER 32000
|
||||
#define LINK_UNIVERSAL_INIT_WAIT_FRAMES 10
|
||||
#define LINK_UNIVERSAL_SWITCH_WAIT_FRAMES 25
|
||||
#define LINK_UNIVERSAL_SWITCH_WAIT_FRAMES_RANDOM 10
|
||||
#define LINK_UNIVERSAL_BROADCAST_SEARCH_WAIT_FRAMES 10
|
||||
#define LINK_UNIVERSAL_SERVE_WAIT_FRAMES 60
|
||||
#define LINK_UNIVERSAL_SERVE_WAIT_FRAMES_RANDOM 30
|
||||
|
||||
static volatile char LINK_UNIVERSAL_VERSION[] = "LinkUniversal/v7.0.0";
|
||||
|
||||
void LINK_UNIVERSAL_ISR_VBLANK();
|
||||
void LINK_UNIVERSAL_ISR_SERIAL();
|
||||
void LINK_UNIVERSAL_ISR_TIMER();
|
||||
#define LINK_UNIVERSAL_DISCONNECTED LINK_CABLE_DISCONNECTED
|
||||
#define LINK_UNIVERSAL_NO_DATA LINK_CABLE_NO_DATA
|
||||
|
||||
class LinkUniversal {
|
||||
private:
|
||||
using u32 = unsigned int;
|
||||
using u16 = unsigned short;
|
||||
using u8 = unsigned char;
|
||||
using s8 = signed char;
|
||||
|
||||
static constexpr int MAX_ROOM_NUMBER = 32000;
|
||||
static constexpr int INIT_WAIT_FRAMES = 10;
|
||||
static constexpr int SWITCH_WAIT_FRAMES = 25;
|
||||
static constexpr int SWITCH_WAIT_FRAMES_RANDOM = 10;
|
||||
static constexpr int BROADCAST_SEARCH_WAIT_FRAMES = 10;
|
||||
static constexpr int SERVE_WAIT_FRAMES = 60;
|
||||
static constexpr int SERVE_WAIT_FRAMES_RANDOM = 30;
|
||||
|
||||
public:
|
||||
enum State { INITIALIZING, WAITING, CONNECTED };
|
||||
enum Mode { LINK_CABLE, LINK_WIRELESS };
|
||||
@@ -104,25 +106,29 @@ class LinkUniversal {
|
||||
s8 asyncACKTimerId;
|
||||
};
|
||||
|
||||
explicit LinkUniversal(
|
||||
Protocol protocol = AUTODETECT,
|
||||
const char* gameName = "",
|
||||
CableOptions cableOptions =
|
||||
CableOptions{
|
||||
LinkCable::BaudRate::BAUD_RATE_1, LINK_CABLE_DEFAULT_TIMEOUT,
|
||||
LINK_CABLE_DEFAULT_REMOTE_TIMEOUT, LINK_CABLE_DEFAULT_INTERVAL,
|
||||
LINK_CABLE_DEFAULT_SEND_TIMER_ID},
|
||||
WirelessOptions wirelessOptions = WirelessOptions{
|
||||
true, LINK_UNIVERSAL_MAX_PLAYERS, LINK_WIRELESS_DEFAULT_TIMEOUT,
|
||||
LINK_WIRELESS_DEFAULT_REMOTE_TIMEOUT, LINK_WIRELESS_DEFAULT_INTERVAL,
|
||||
LINK_WIRELESS_DEFAULT_SEND_TIMER_ID,
|
||||
LINK_WIRELESS_DEFAULT_ASYNC_ACK_TIMER_ID}) {
|
||||
explicit LinkUniversal(Protocol protocol = AUTODETECT,
|
||||
const char* gameName = "",
|
||||
CableOptions cableOptions =
|
||||
CableOptions{LinkCable::BaudRate::BAUD_RATE_1,
|
||||
LINK_CABLE_DEFAULT_TIMEOUT,
|
||||
LINK_CABLE_DEFAULT_REMOTE_TIMEOUT,
|
||||
LINK_CABLE_DEFAULT_INTERVAL,
|
||||
LINK_CABLE_DEFAULT_SEND_TIMER_ID},
|
||||
WirelessOptions wirelessOptions =
|
||||
WirelessOptions{
|
||||
true, LINK_UNIVERSAL_MAX_PLAYERS,
|
||||
LINK_WIRELESS_DEFAULT_TIMEOUT,
|
||||
LINK_WIRELESS_DEFAULT_REMOTE_TIMEOUT,
|
||||
LINK_WIRELESS_DEFAULT_INTERVAL,
|
||||
LINK_WIRELESS_DEFAULT_SEND_TIMER_ID,
|
||||
LINK_WIRELESS_DEFAULT_ASYNC_ACK_TIMER_ID},
|
||||
int randomSeed = 123) {
|
||||
this->linkCable = new LinkCable(
|
||||
cableOptions.baudRate, cableOptions.timeout, cableOptions.remoteTimeout,
|
||||
cableOptions.interval, cableOptions.sendTimerId);
|
||||
this->linkWireless = new LinkWireless(
|
||||
wirelessOptions.retransmission, true,
|
||||
min(wirelessOptions.maxPlayers, LINK_UNIVERSAL_MAX_PLAYERS),
|
||||
Link::_min(wirelessOptions.maxPlayers, LINK_UNIVERSAL_MAX_PLAYERS),
|
||||
wirelessOptions.timeout, wirelessOptions.remoteTimeout,
|
||||
wirelessOptions.interval, wirelessOptions.sendTimerId,
|
||||
wirelessOptions.asyncACKTimerId);
|
||||
@@ -131,7 +137,7 @@ class LinkUniversal {
|
||||
this->config.gameName = gameName;
|
||||
}
|
||||
|
||||
bool isActive() { return isEnabled; }
|
||||
[[nodiscard]] bool isActive() { return isEnabled; }
|
||||
|
||||
void activate() {
|
||||
reset();
|
||||
@@ -146,16 +152,16 @@ class LinkUniversal {
|
||||
}
|
||||
|
||||
void setProtocol(Protocol protocol) { this->config.protocol = protocol; }
|
||||
Protocol getProtocol() { return this->config.protocol; }
|
||||
[[nodiscard]] Protocol getProtocol() { return this->config.protocol; }
|
||||
|
||||
bool isConnected() { return state == CONNECTED; }
|
||||
[[nodiscard]] bool isConnected() { return state == CONNECTED; }
|
||||
|
||||
u8 playerCount() {
|
||||
[[nodiscard]] u8 playerCount() {
|
||||
return mode == LINK_CABLE ? linkCable->playerCount()
|
||||
: linkWireless->playerCount();
|
||||
}
|
||||
|
||||
u8 currentPlayerId() {
|
||||
[[nodiscard]] u8 currentPlayerId() {
|
||||
return mode == LINK_CABLE ? linkCable->currentPlayerId()
|
||||
: linkWireless->currentPlayerId();
|
||||
}
|
||||
@@ -164,10 +170,10 @@ class LinkUniversal {
|
||||
if (!isEnabled)
|
||||
return;
|
||||
|
||||
u16 keys = ~REG_KEYS & KEY_ANY;
|
||||
__qran_seed += keys;
|
||||
__qran_seed += REG_RCNT;
|
||||
__qran_seed += REG_SIOCNT;
|
||||
u16 keys = ~Link::_REG_KEYS & Link::_KEY_ANY;
|
||||
randomSeed += keys;
|
||||
randomSeed += Link::_REG_RCNT;
|
||||
randomSeed += Link::_REG_SIOCNT;
|
||||
|
||||
if (mode == LINK_CABLE)
|
||||
linkCable->sync();
|
||||
@@ -175,7 +181,7 @@ class LinkUniversal {
|
||||
switch (state) {
|
||||
case INITIALIZING: {
|
||||
waitCount++;
|
||||
if (waitCount > LINK_UNIVERSAL_INIT_WAIT_FRAMES)
|
||||
if (waitCount > INIT_WAIT_FRAMES)
|
||||
start();
|
||||
break;
|
||||
};
|
||||
@@ -242,18 +248,22 @@ class LinkUniversal {
|
||||
: linkWireless->config.sendTimerId;
|
||||
|
||||
while (isConnected() && !canRead(playerId) && !cancel()) {
|
||||
IntrWait(1, IRQ_SERIAL | LINK_CABLE_TIMER_IRQ_IDS[timerId]);
|
||||
Link::_IntrWait(1, Link::_IRQ_SERIAL | Link::_TIMER_IRQ_IDS[timerId]);
|
||||
sync();
|
||||
}
|
||||
|
||||
return isConnected() && canRead(playerId);
|
||||
}
|
||||
|
||||
bool canRead(u8 playerId) { return !incomingMessages[playerId].isEmpty(); }
|
||||
[[nodiscard]] bool canRead(u8 playerId) {
|
||||
return !incomingMessages[playerId].isEmpty();
|
||||
}
|
||||
|
||||
u16 read(u8 playerId) { return incomingMessages[playerId].pop(); }
|
||||
|
||||
u16 peek(u8 playerId) { return incomingMessages[playerId].peek(); }
|
||||
[[nodiscard]] u16 peek(u8 playerId) {
|
||||
return incomingMessages[playerId].peek();
|
||||
}
|
||||
|
||||
bool send(u16 data) {
|
||||
if (data == LINK_CABLE_DISCONNECTED || data == LINK_CABLE_NO_DATA)
|
||||
@@ -267,17 +277,19 @@ class LinkUniversal {
|
||||
}
|
||||
}
|
||||
|
||||
State getState() { return state; }
|
||||
Mode getMode() { return mode; }
|
||||
LinkWireless::State getWirelessState() { return linkWireless->getState(); }
|
||||
[[nodiscard]] State getState() { return state; }
|
||||
[[nodiscard]] Mode getMode() { return mode; }
|
||||
[[nodiscard]] LinkWireless::State getWirelessState() {
|
||||
return linkWireless->getState();
|
||||
}
|
||||
|
||||
~LinkUniversal() {
|
||||
delete linkCable;
|
||||
delete linkWireless;
|
||||
}
|
||||
|
||||
u32 _getWaitCount() { return waitCount; }
|
||||
u32 _getSubWaitCount() { return subWaitCount; }
|
||||
[[nodiscard]] u32 _getWaitCount() { return waitCount; }
|
||||
[[nodiscard]] u32 _getSubWaitCount() { return subWaitCount; }
|
||||
|
||||
void _onVBlank() {
|
||||
if (mode == LINK_CABLE)
|
||||
@@ -322,13 +334,16 @@ class LinkUniversal {
|
||||
u32 switchWait = 0;
|
||||
u32 subWaitCount = 0;
|
||||
u32 serveWait = 0;
|
||||
int randomSeed = 0;
|
||||
volatile bool isEnabled = false;
|
||||
|
||||
void receiveCableMessages() {
|
||||
int maxPlayers =
|
||||
min(LINK_CABLE_MAX_PLAYERS,
|
||||
LINK_UNIVERSAL_MAX_PLAYERS); // TODO: MOVE TO CONSTEXPR
|
||||
for (u32 i = 0; i < maxPlayers; i++) {
|
||||
static constexpr u32 MAX_PLAYERS =
|
||||
LINK_CABLE_MAX_PLAYERS < LINK_UNIVERSAL_MAX_PLAYERS
|
||||
? LINK_CABLE_MAX_PLAYERS
|
||||
: LINK_UNIVERSAL_MAX_PLAYERS;
|
||||
|
||||
for (u32 i = 0; i < MAX_PLAYERS; i++) {
|
||||
while (linkCable->canRead(i))
|
||||
incomingMessages[i].push(linkCable->read(i));
|
||||
}
|
||||
@@ -360,7 +375,7 @@ class LinkUniversal {
|
||||
waitCount = 0;
|
||||
subWaitCount++;
|
||||
|
||||
if (subWaitCount >= LINK_UNIVERSAL_BROADCAST_SEARCH_WAIT_FRAMES) {
|
||||
if (subWaitCount >= BROADCAST_SEARCH_WAIT_FRAMES) {
|
||||
if (!tryConnectOrServeWirelessSession())
|
||||
return false;
|
||||
}
|
||||
@@ -407,8 +422,7 @@ class LinkUniversal {
|
||||
(LINK_UNIVERSAL_GAME_ID_FILTER == 0 ||
|
||||
server.gameId == LINK_UNIVERSAL_GAME_ID_FILTER)) {
|
||||
u32 randomNumber = safeStoi(server.userName);
|
||||
if (randomNumber > maxRandomNumber &&
|
||||
randomNumber < LINK_UNIVERSAL_MAX_ROOM_NUMBER) {
|
||||
if (randomNumber > maxRandomNumber && randomNumber < MAX_ROOM_NUMBER) {
|
||||
maxRandomNumber = randomNumber;
|
||||
serverIndex = i;
|
||||
}
|
||||
@@ -423,9 +437,8 @@ class LinkUniversal {
|
||||
return false;
|
||||
|
||||
subWaitCount = 0;
|
||||
serveWait = LINK_UNIVERSAL_SERVE_WAIT_FRAMES +
|
||||
qran_range(1, LINK_UNIVERSAL_SERVE_WAIT_FRAMES_RANDOM);
|
||||
u32 randomNumber = qran_range(1, LINK_UNIVERSAL_MAX_ROOM_NUMBER);
|
||||
serveWait = SERVE_WAIT_FRAMES + _qran_range(1, SERVE_WAIT_FRAMES_RANDOM);
|
||||
u32 randomNumber = _qran_range(1, MAX_ROOM_NUMBER);
|
||||
char randomNumberStr[6];
|
||||
std::snprintf(randomNumberStr, sizeof(randomNumberStr), "%d",
|
||||
randomNumber);
|
||||
@@ -503,8 +516,7 @@ class LinkUniversal {
|
||||
|
||||
void resetState() {
|
||||
waitCount = 0;
|
||||
switchWait = LINK_UNIVERSAL_SWITCH_WAIT_FRAMES +
|
||||
qran_range(1, LINK_UNIVERSAL_SWITCH_WAIT_FRAMES_RANDOM);
|
||||
switchWait = SWITCH_WAIT_FRAMES + _qran_range(1, SWITCH_WAIT_FRAMES_RANDOM);
|
||||
subWaitCount = 0;
|
||||
serveWait = 0;
|
||||
for (u32 i = 0; i < LINK_UNIVERSAL_MAX_PLAYERS; i++)
|
||||
@@ -524,6 +536,15 @@ class LinkUniversal {
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
int _qran(void) {
|
||||
randomSeed = 1664525 * randomSeed + 1013904223;
|
||||
return (randomSeed >> 16) & 0x7FFF;
|
||||
}
|
||||
|
||||
int _qran_range(int min, int max) {
|
||||
return (_qran() * (max - min) >> 15) + min;
|
||||
}
|
||||
};
|
||||
|
||||
extern LinkUniversal* linkUniversal;
|
||||
|
||||
@@ -106,6 +106,7 @@ static volatile char LINK_WIRELESS_VERSION[] = "LinkWireless/v7.0.0";
|
||||
|
||||
#define LINK_WIRELESS_MAX_PLAYERS 5
|
||||
#define LINK_WIRELESS_MIN_PLAYERS 2
|
||||
#define LINK_WIRELESS_END 0
|
||||
#define LINK_WIRELESS_MAX_COMMAND_TRANSFER_LENGTH 22
|
||||
#define LINK_WIRELESS_MAX_COMMAND_RESPONSE_LENGTH 30
|
||||
#define LINK_WIRELESS_BROADCAST_LENGTH 6
|
||||
@@ -114,7 +115,9 @@ static volatile char LINK_WIRELESS_VERSION[] = "LinkWireless/v7.0.0";
|
||||
#define LINK_WIRELESS_MAX_SERVERS \
|
||||
(LINK_WIRELESS_MAX_COMMAND_RESPONSE_LENGTH / \
|
||||
LINK_WIRELESS_BROADCAST_RESPONSE_LENGTH)
|
||||
#define LINK_WIRELESS_END 0
|
||||
#define LINK_WIRELESS_MAX_GAME_ID 0x7fff
|
||||
#define LINK_WIRELESS_MAX_GAME_NAME_LENGTH 14
|
||||
#define LINK_WIRELESS_MAX_USER_NAME_LENGTH 8
|
||||
#define LINK_WIRELESS_DEFAULT_TIMEOUT 10
|
||||
#define LINK_WIRELESS_DEFAULT_REMOTE_TIMEOUT 10
|
||||
#define LINK_WIRELESS_DEFAULT_INTERVAL 50
|
||||
@@ -153,9 +156,6 @@ class LinkWireless {
|
||||
static constexpr int TRANSFER_WAIT = 15;
|
||||
static constexpr int BROADCAST_SEARCH_WAIT_FRAMES = 60;
|
||||
static constexpr int CMD_TIMEOUT = 100;
|
||||
static constexpr int MAX_GAME_ID = 0x7fff;
|
||||
static constexpr int MAX_GAME_NAME_LENGTH = 14;
|
||||
static constexpr int MAX_USER_NAME_LENGTH = 8;
|
||||
static constexpr int LOGIN_STEPS = 9;
|
||||
static constexpr int COMMAND_HEADER_VALUE = 0x9966;
|
||||
static constexpr int RESPONSE_ACK_VALUE = 0x80;
|
||||
@@ -233,8 +233,8 @@ class LinkWireless {
|
||||
struct Server {
|
||||
u16 id = 0;
|
||||
u16 gameId;
|
||||
char gameName[MAX_GAME_NAME_LENGTH + 1];
|
||||
char userName[MAX_USER_NAME_LENGTH + 1];
|
||||
char gameName[LINK_WIRELESS_MAX_GAME_NAME_LENGTH + 1];
|
||||
char userName[LINK_WIRELESS_MAX_USER_NAME_LENGTH + 1];
|
||||
u8 currentPlayerCount;
|
||||
|
||||
bool isFull() { return currentPlayerCount == 0; }
|
||||
@@ -332,7 +332,7 @@ class LinkWireless {
|
||||
*/
|
||||
bool serve(const char* gameName = "",
|
||||
const char* userName = "",
|
||||
u16 gameId = MAX_GAME_ID) {
|
||||
u16 gameId = LINK_WIRELESS_MAX_GAME_ID) {
|
||||
LINK_WIRELESS_RESET_IF_NEEDED
|
||||
if (state != AUTHENTICATED && state != SERVING) {
|
||||
lastError = WRONG_STATE;
|
||||
@@ -342,25 +342,25 @@ class LinkWireless {
|
||||
lastError = BUSY_TRY_AGAIN;
|
||||
return false;
|
||||
}
|
||||
if (std::strlen(gameName) > MAX_GAME_NAME_LENGTH) {
|
||||
if (std::strlen(gameName) > LINK_WIRELESS_MAX_GAME_NAME_LENGTH) {
|
||||
lastError = GAME_NAME_TOO_LONG;
|
||||
return false;
|
||||
}
|
||||
if (std::strlen(userName) > MAX_GAME_NAME_LENGTH) {
|
||||
if (std::strlen(userName) > LINK_WIRELESS_MAX_GAME_NAME_LENGTH) {
|
||||
lastError = USER_NAME_TOO_LONG;
|
||||
return false;
|
||||
}
|
||||
|
||||
char finalGameName[MAX_GAME_NAME_LENGTH + 1];
|
||||
char finalUserName[MAX_USER_NAME_LENGTH + 1];
|
||||
copyName(finalGameName, gameName, MAX_GAME_NAME_LENGTH);
|
||||
copyName(finalUserName, userName, MAX_USER_NAME_LENGTH);
|
||||
char finalGameName[LINK_WIRELESS_MAX_GAME_NAME_LENGTH + 1];
|
||||
char finalUserName[LINK_WIRELESS_MAX_USER_NAME_LENGTH + 1];
|
||||
copyName(finalGameName, gameName, LINK_WIRELESS_MAX_GAME_NAME_LENGTH);
|
||||
copyName(finalUserName, userName, LINK_WIRELESS_MAX_USER_NAME_LENGTH);
|
||||
|
||||
if (state != SERVING)
|
||||
setup(config.maxPlayers);
|
||||
|
||||
addData(buildU32(buildU16(finalGameName[1], finalGameName[0]),
|
||||
gameId & MAX_GAME_ID),
|
||||
gameId & LINK_WIRELESS_MAX_GAME_ID),
|
||||
true);
|
||||
addData(buildU32(buildU16(finalGameName[5], finalGameName[4]),
|
||||
buildU16(finalGameName[3], finalGameName[2])));
|
||||
@@ -486,7 +486,7 @@ class LinkWireless {
|
||||
|
||||
Server server;
|
||||
server.id = (u16)result.responses[start];
|
||||
server.gameId = result.responses[start + 1] & MAX_GAME_ID;
|
||||
server.gameId = result.responses[start + 1] & LINK_WIRELESS_MAX_GAME_ID;
|
||||
u32 gameI = 0, userI = 0;
|
||||
recoverName(server.gameName, gameI, result.responses[start + 1], false);
|
||||
recoverName(server.gameName, gameI, result.responses[start + 2]);
|
||||
|
||||
@@ -75,15 +75,19 @@ inline volatile u16* const _REG_SIOMULTI =
|
||||
inline volatile u16& _REG_VCOUNT =
|
||||
*reinterpret_cast<volatile u16*>(_REG_BASE + 0x0006);
|
||||
|
||||
inline volatile u16& _REG_KEYS =
|
||||
*reinterpret_cast<volatile u16*>(_REG_BASE + 0x0130);
|
||||
|
||||
inline volatile _TMR_REC* const _REG_TM =
|
||||
reinterpret_cast<volatile _TMR_REC*>(_REG_BASE + 0x0100);
|
||||
|
||||
static constexpr u16 _TM_FREQ_1 = 0; // 1 cycle/tick (16.7 MHz)
|
||||
static constexpr u16 _TM_FREQ_64 = 0x0001; // 64 cycles/tick (262 kHz)
|
||||
static constexpr u16 _TM_FREQ_256 = 0x0002; // 256 cycles/tick (66 kHz)
|
||||
static constexpr u16 _TM_FREQ_1024 = 0x0003; // 1024 cycles/tick (16 kHz)
|
||||
static constexpr u16 _TM_IRQ = 0x0040;
|
||||
static constexpr u16 _TM_ENABLE = 0x0080;
|
||||
static constexpr u16 _KEY_ANY = 0x03FF; //!< Here's the Any key :)
|
||||
static constexpr u16 _TM_FREQ_1 = 0; //!< 1 cycle/tick (16.7 MHz)
|
||||
static constexpr u16 _TM_FREQ_64 = 0x0001; //!< 64 cycles/tick (262 kHz)
|
||||
static constexpr u16 _TM_FREQ_256 = 0x0002; //!< 256 cycles/tick (66 kHz)
|
||||
static constexpr u16 _TM_FREQ_1024 = 0x0003; //!< 1024 cycles/tick (16 kHz)
|
||||
static constexpr u16 _TM_IRQ = 0x0040; //!< Enable timer irq
|
||||
static constexpr u16 _TM_ENABLE = 0x0080; //!< Enable timer
|
||||
|
||||
static constexpr u16 _IRQ_VBLANK = 0x0001; //!< Catch VBlank irq
|
||||
static constexpr u16 _IRQ_TIMER0 = 0x0008; //!< Catch timer 0 irq
|
||||
|
||||
Reference in New Issue
Block a user