diff --git a/source/Network.c b/source/Network.c new file mode 100644 index 0000000..934a20e --- /dev/null +++ b/source/Network.c @@ -0,0 +1,195 @@ +#include "Network.h" + +#include +#include +#include + +bool udsRunning; + +size_t scannedNetworksCount; +udsNetworkScanInfo *scannedNetworks; + +bool isConnected; +bool isServer; + +size_t networkBufferSize; +u32 *networkBuffer; + +udsNetworkStruct networkStruct; +udsBindContext networkBindCtx; + +void networkInit() { + Result ret = udsInit(0x3000, NULL); + if(R_FAILED(ret)) { + udsRunning = false; + } else { + udsRunning = true; + + scannedNetworksCount = 0; + scannedNetworks = NULL; + isConnected = false; + isServer = false; + + networkBufferSize = 0x4000; + networkBuffer = malloc(networkBufferSize); + } +} + +void networkExit() { + //TODO: Additionally to shutting down the service, clear any left over memory! + if(udsRunning) { + //cleanup any dynamically reserved memory + if(scannedNetworks!=NULL) free(scannedNetworks); + scannedNetworks = NULL; + + free(networkBuffer); + networkDisconnect(); + + udsExit(); + } +} + + + +bool networkAvailable() { + return udsRunning; +} + + + +bool networkHost() { + if(udsRunning && !isConnected) { + udsGenerateDefaultNetworkStruct(&networkStruct, NETWORK_WLANCOMMID, 0, NETWORK_MAXPLAYERS); + + Result ret = udsCreateNetwork(&networkStruct, NETWORK_PASSPHRASE, strlen(NETWORK_PASSPHRASE)+1, &networkBindCtx, NETWORK_CHANNEL, NETWORK_RECVBUFSIZE); + if(R_FAILED(ret)) { + return false; + } else { + isConnected = true; + isServer = true; + return true; + } + } + return false; +} + +void networkScan() { + if(udsRunning) { + //reset values from last scan + if(scannedNetworks!=NULL) free(scannedNetworks); + scannedNetworks = NULL; + scannedNetworksCount = 0; + + //scan + memset(networkBuffer, 0, networkBufferSize); + Result ret = udsScanBeacons(networkBuffer, networkBufferSize, &scannedNetworks, &scannedNetworksCount, NETWORK_WLANCOMMID, 0, NULL, isConnected); + if(R_FAILED(ret)) { + //TODO: what do? + scannedNetworksCount = 0; + } + } +} + +int networkGetScanCount() { + if(udsRunning) { + return scannedNetworksCount; + } else { + return 0; + } +} + +bool networkGetScanName(char *name, int pos) { + if(udsRunning) { + if(pos<0 || pos>=scannedNetworksCount) return false; + + Result ret = udsGetNodeInfoUsername(&scannedNetworks[pos].nodes[0], name); + if(R_FAILED(ret)) { + //TODO: what do? + return false; + } + return true; + } + return false; +} + +bool networkConnect(int pos) { + if(udsRunning && !isConnected) { + if(pos<0 || pos>=scannedNetworksCount) return false; + + Result ret = udsConnectNetwork(&scannedNetworks[pos].network, NETWORK_PASSPHRASE, strlen(NETWORK_PASSPHRASE)+1, &networkBindCtx, UDS_BROADCAST_NETWORKNODEID, UDSCONTYPE_Client, NETWORK_CHANNEL, NETWORK_RECVBUFSIZE); + if(R_FAILED(ret)) { + return false; + } else { + isConnected = true; + isServer = false; + return true; + } + } + return false; +} + +void networkDisconnect() { + //TODO: For clients this just means disconnect, for the server it means destroy the network + if(udsRunning && isConnected) { + //TODO + if(isServer) { + udsDisconnectNetwork(); + } else { + //TODO: Clients need to cleanup too, how can I tell they got disconnected + udsDestroyNetwork(); + } + udsUnbind(&networkBindCtx); + + isConnected = false; + } +} + + + +bool networkConnected() { + return isConnected; +} + + + +void networkSend(networkPacket *packet, size_t size) { + if(udsRunning && isConnected) { + //Server broadcasts to all clients but clients only send info to server + u16 dest; + if(isServer) { + dest = UDS_BROADCAST_NETWORKNODEID; + } else { + dest = UDS_HOST_NETWORKNODEID; + } + + Result ret = udsSendTo(dest, NETWORK_CHANNEL, UDS_SENDFLAG_Default, packet, size); + if(UDS_CHECK_SENDTO_FATALERROR(ret)) { + //TODO: what do? + } + } +} + +void networkRecieve() { + //TODO: Should recieve actually handle all the packets or just return them? + if(udsRunning && isConnected) { + size_t actualSize = 0; + u16 sourceNetworkNodeID; + + memset(networkBuffer, 0, networkBufferSize); + + Result ret = udsPullPacket(&networkBindCtx, networkBuffer, networkBufferSize, &actualSize, &sourceNetworkNodeID); + if(R_FAILED(ret)) { + //TODO: what do? + } + + //actualSize will be 0 if no packet is available + if(actualSize) { + networkPacket *packet = (networkPacket*) networkBuffer; + + //TODO: Differenciate the packets and process them + if(packet->analyze.type==0) { + + } + } + } +} diff --git a/source/Network.h b/source/Network.h new file mode 100644 index 0000000..697cdb8 --- /dev/null +++ b/source/Network.h @@ -0,0 +1,40 @@ +#pragma once + +#include <3ds.h> + +#define NETWORK_WLANCOMMID 0x11441850 +#define NETWORK_PASSPHRASE "minicraft3ds localplay passphrase" +#define NETWORK_CHANNEL 1 + +#define NETWORK_RECVBUFSIZE UDS_DEFAULT_RECVBUFSIZE + +#define NETWORK_MAXPLAYERS UDS_MAXNODES + +//TODO: Every other packet struct should start with a u8 type to match this +typedef struct { + u8 type; +} packetAnalyze; + +typedef struct { + union { + packetAnalyze analyze; + + }; +} networkPacket; + +void networkInit(); +void networkExit(); + +bool networkAvailable(); + +bool networkHost(); +void networkScan(); +int networkGetScanCount(); +bool networkGetScanName(char *name, int pos); //TODO: Name should be long enough to handle all allowed names (char[256]) +bool networkConnect(int pos); +void networkDisconnect(); + +bool networkConnected(); + +void networkSend(networkPacket *packet, size_t size); //TODO: Should this be a pointer? Calling function needs to cleanup itself +void networkRecieve(); //TODO: Should recieve actually handle all the packets or just return them? diff --git a/source/Quests.c b/source/Quests.c index 5836003..a34eeaf 100644 --- a/source/Quests.c +++ b/source/Quests.c @@ -124,7 +124,7 @@ void openNPCMenu(int npc) { currentTalk2 = "or stupid to be walking"; currentTalk3 = "around in this dungeon."; currentTalk4 = ""; - currentTalk5 = "Who can I help you?"; + currentTalk5 = "How can I help you?"; break; case NPC_DWARF: if(questManager.questlines[1].currentQuest<=1) { diff --git a/source/main.c b/source/main.c index 9b21c2f..80d22e0 100644 --- a/source/main.c +++ b/source/main.c @@ -12,6 +12,7 @@ #include "MapGen.h" #include "Menu.h" #include "texturepack.h" +#include "Network.h" // TODO: Dungeon is way to difficult // -> Skeleton arrows are slower, do a little less damage @@ -182,9 +183,10 @@ int main() { osSetSpeedupEnable(shouldSpeedup); fclose(file); } - - sf2d_init(); + sf2d_init(); csndInit(); + networkInit(); + noItem = newItem(ITEM_NULL, 0); initMenus(); @@ -325,6 +327,7 @@ int main() { sf2d_free_texture(minimap[4]); sf2d_free_texture(minimap[5]); freeSounds(); + networkExit(); csndExit(); cfguExit(); sf2d_fini();